我目前正在研究 CityGML (de)serializer - 我需要某些相应对象的 C# 类 - 我在 System.Xml.Serialization.XmlSerializer 实例所需的根类方面遇到了一些问题。不知道大家对CityGML有多熟悉,这里先说一下情况。我还描述了我是如何创建我的类的,如果你想跳过这个,你可以从/ /* 标记开始阅读:
CityGML 由多个 .xsd 文件组成,每个文件都是描述某种类型元素(appearance.xsd、transports.xsd、building.xsd、vegetation.xsd 等)的模块,还有一个根文件 CityGML.xsd。如您所料,每个模块都需要此根文件中的元素。还有一个事实是 CityGML 实际上从 GML 继承了很多,所以从 GML .xsd 文件导入也是必要的。
到目前为止,在 C# 类生成方面,我尝试了两种方法,都使用经典的 xsd.exe: - 创建一个 .cs 文件,其中将包含我需要的所有 CityGML 类 - 一个命令行:
xsd gml/feature.xsd gml/xlinks.xsd gml/geometryBasic2d.xsd gml/geometryComplexes.xsd gml/geometryPrimitives.xsd gml/smil20.xsd
gml/smil20-language.xsd citygml/xAL.xsd citygml/appearance.xsd citygml/building.xsd citygml/cityFurniture.xsd citygml/cityObjectGroup.xsd
citygml/generics.xsd citygml/landUse.xsd citygml/relief.xsd citygml/texturedSurface.xsd citygml/transportation.xsd citygml/vegetation.xsd
citygml/waterBody.xsd citygml/CityGML.xsd citygml/cityGMLBase.xsd /classes /fields /namespace:CityGML
- the creation of a .cs file for each of the CityGML modules - one command line for each module:
xsd citygml/xAL.xsd /classes /namespace:xAL /o:out
xsd gml/feature.xsd citygml/xAL.xsd gml/geometryAggregates.xsd gml/xlinks.xsd
citygml/cityGMLBase.xsd /classes /namespace:CityGMLBase /o:out
xsd gml/feature.xsd citygml/cityGMLBase.xsd citygml/xAL.xsd gml/geometryAggregates.xsd
gml/xlinks.xsd citygml/appearance.xsd /classes /namespace:CityGMLAppearance /o:out
xsd gml/feature.xsd citygml/cityGMLBase.xsd citygml/xAL.xsd gml/geometryAggregates.xsd gml/xlinks.xsd citygml/building.xsd /classes /namespace:CityGMLBuilding /o:out
xsd gml/feature.xsd citygml/cityGMLBase.xsd citygml/xAL.xsd gml/geometryAggregates.xsd gml/xlinks.xsd citygml/cityFurniture.xsd /classes /namespace:CityGMLCityFurniture /o:out
xsd citygml/cityGMLBase.xsd gml/feature.xsd gml/xlinks.xsd citygml/xAL.xsd gml/geometryAggregates.xsd citygml/cityObjectGroup.xsd /classes /namespace:CityGMLCityObjectGroup /o:out
xsd gml/feature.xsd citygml/cityGMLBase.xsd citygml/xAL.xsd gml/geometryAggregates.xsd gml/xlinks.xsd citygml/generics.xsd /classes /namespace:CityGMLGenerics /o:out
xsd gml/feature.xsd citygml/cityGMLBase.xsd citygml/xAL.xsd gml/geometryAggregates.xsd gml/xlinks.xsd citygml/landUse.xsd /classes /namespace:CityGMLLandUse /o:out
xsd citygml/cityGMLBase.xsd citygml/xAL.xsd gml/xlinks.xsd citygml/cityFurniture.xsd gml/coverage.xsd citygml/relief.xsd /classes /namespace:CityGMLRelief /o:out
xsd gml/feature.xsd citygml/cityGMLBase.xsd citygml/xAL.xsd gml/geometryAggregates.xsd gml/xlinks.xsd citygml/texturedSurface.xsd /classes /namespace:CityGMLTexturedSurface /o:out
xsd gml/feature.xsd citygml/cityGMLBase.xsd citygml/xAL.xsd gml/geometryComplexes.xsd gml/xlinks.xsd citygml/transportation.xsd /classes /namespace:CityGMLTransportation /o:out
xsd gml/feature.xsd citygml/cityGMLBase.xsd citygml/xAL.xsd gml/geometryAggregates.xsd
gml/xlinks.xsd citygml/vegetation.xsd /classes /namespace:CityGMLVegetation /o:out
xsd gml/feature.xsd citygml/cityGMLBase.xsd citygml/xAL.xsd gml/geometryAggregates.xsd gml/xlinks.xsd citygml/waterBody.xsd /classes /namespace:CityGMLWaterBody /o:out
对于每个命令,最后一个 .xsd 是所需的模块,而其他的则是必要的导入。
不幸的是,尽管 xsd.exe 处理来自其他 .xsd 文件的导入,并且它会创建所需文件以及导入文件的类,但它非常“直接”地执行此操作,将所有这些类堆叠在一个 .cs 文件中。显然,无法将所需的类与不同 .cs 文件中的导入类分开。因此,我的第一个问题是是否有任何(反)序列化工具,类似于 XSD.EXE,可以处理导入的 .XSD 文件并创建特定的 .CS 文件层次结构?这将避免重复,例如,上述所有模块 .cs 文件中的 feature.xsd 类。
/ /*
继续前进,实际上给我带来麻烦的问题与 XmlSerializer 实例有关,该实例无法创建,因为基本的 CityGML 对象类型 CityModelType(也是整个层次结构中的根类)并不完全有效:
System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(CityModelType));
这个赋值首先产生了一个关于使用 XmlTextAttribute 定义 string[] 的错误,这使得 CityModelType 的“反射”变得不可能。我用 XmlAttributeAttribute 替换了 XmlTextAttribute 并且我无法追踪其来源的当前消息是这些(是的,我正在用法语工作):
System.InvalidOperationException: Impossible de générer une classe temporaire (result=1).
error CS0030: Impossible de convertir le type 'CityGML.LineStringSegmentType[]' en 'CityGML.LineStringSegmentType'
error CS0030: Impossible de convertir le type 'CityGML.LineStringSegmentType[]' en 'CityGML.LineStringSegmentType'
error CS0030: Impossible de convertir le type 'CityGML.LineStringSegmentType[]' en 'CityGML.LineStringSegmentType'
error CS0029: Impossible de convertir implicitement le type 'CityGML.LineStringSegmentType' en 'CityGML.LineStringSegmentType[]'
error CS0029: Impossible de convertir implicitement le type 'CityGML.LineStringSegmentType' en 'CityGML.LineStringSegmentType[]'
error CS0029: Impossible de convertir implicitement le type 'CityGML.LineStringSegmentType' en 'CityGML.LineStringSegmentType[]'
首先, LineStringSegmentType 的唯一出现与曲线有关,我没有在我的 .gml 文件中使用。它们的定义如下:
public partial class LineStringSegmentType : AbstractCurveSegmentType {
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("coordinates", typeof(CoordinatesType))]
[System.Xml.Serialization.XmlElementAttribute("pointProperty", typeof(PointPropertyType))]
[System.Xml.Serialization.XmlElementAttribute("pointRep", typeof(PointPropertyType))]
[System.Xml.Serialization.XmlElementAttribute("pos", typeof(DirectPositionType))]
[System.Xml.Serialization.XmlElementAttribute("posList", typeof(DirectPositionListType))]
[System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemsElementName")]
public object[] Items;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("ItemsElementName")]
[System.Xml.Serialization.XmlIgnoreAttribute()]
public ItemsChoiceType2[] ItemsElementName;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public CurveInterpolationType interpolation;
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool interpolationSpecified;
public LineStringSegmentType() {
this.interpolation = CurveInterpolationType.linear;
}
}
...在这里使用它们:
public partial class TinType : TriangulatedSurfaceType {
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("LineStringSegment", typeof(LineStringSegmentType), IsNullable=false)]
public LineStringSegmentType[][] stopLines;
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("LineStringSegment", typeof(LineStringSegmentType), IsNullable=false)]
public LineStringSegmentType[][] breakLines;
/// <remarks/>
public LengthType maxLength;
/// <remarks/>
public TinTypeControlPoint controlPoint;
}
...来自这个 gml:geometryPrimitives.xsd 片段:
<complexType name="TinType">
[...]
<complexContent>
<extension base="gml:TriangulatedSurfaceType">
<sequence>
<element name="stopLines" type="gml:LineStringSegmentArrayPropertyType" minOccurs="0" maxOccurs="unbounded">
[...]
</element>
<element name="breakLines" type="gml:LineStringSegmentArrayPropertyType" minOccurs="0" maxOccurs="unbounded">
[...]
</element>
<element name="maxLength" type="gml:LengthType">
[...]
</element>
<element name="controlPoint">
[...]
<complexType>
<choice>
<element ref="gml:posList"/>
<group ref="gml:geometricPositionGroup" minOccurs="3" maxOccurs="unbounded"/>
</choice>
</complexType>
</element>
</sequence>
</extension>
</complexContent>
</complexType>
<complexType name="LineStringSegmentArrayPropertyType">
<sequence>
<element ref="gml:LineStringSegment" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
我看不出问题出在哪里,这很奇怪。希望早日收到你的消息。谢谢。
干杯,维克多