我有一个由数据提供者提供给我们的XSD架构。我不能修改它。我使用XSD.exe命令行工具生成了类。对于它完美运行的一切,我可以用C#创建我的对象,用XML序列化它并根据XSD验证它。
我的一小部分问题。预期的输出是:
<Physical>
<Class>P</Class>
<Capacity>14</Capacity>
<Class>J</Class>
<Capacity>64</Capacity>
<Class>W</Class>
<Capacity>1</Capacity>
<Class>Y</Class>
<Capacity>2</Capacity>
</Physical>
<Saleable Protected="true">
<Class>P</Class>
<Capacity>14</Capacity>
<Class>J</Class>
<Capacity>64</Capacity>
<Class>W</Class>
<Capacity>1</Capacity>
<Class>Y</Class>
<Capacity>2</Capacity>
</Saleable>
正如您所看到的,物理和可密封备用的子元素(即类,然后是容量,然后是类,然后是容量等)。
这是由XSD.exe生成的类的代码:
public partial class ClassA
{
private string[] classField;
private Integerctype[] capacityField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Class", DataType = "token")]
public string[] Class
{
get
{
return this.classField;
}
set
{
this.classField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Capacity", IsNullable = true)]
public Integerctype[] Capacity
{
get
{
return this.capacityField;
}
set
{
this.capacityField = value;
}
}
}
序列化后我收到的输出:
<Physical>
<Class>P</Class>
<Class>J</Class>
<Class>W</Class>
<Class>Y</Class>
<Capacity>14</Capacity>
<Capacity>64</Capacity>
<Capacity>1</Capacity>
<Capacity>2</Capacity>
</Physical>
<Saleable>
<Class>P</Class>
<Class>J</Class>
<Class>W</Class>
<Class>Y</Class>
<Capacity>14</Capacity>
<Capacity>64</Capacity>
<Capacity>1</Capacity>
<Capacity>2</Capacity>
</Saleable>
正如您所看到的,我们失去了Class和Capacity之间的交替......
我尝试使用XmlElementAttribute的Order属性:Class属性用Order = 1装饰,而Capacity属性用Order = 2装饰,但它没有帮助。例如:
[System.Xml.Serialization.XmlElementAttribute("Class", DataType = "token", Order = 1)]
public string[] Class
在验证过程中,无论是否有Order属性,我都会收到如下错误:
命名空间“xxx”中的“Physical”元素具有无效的子元素 命名空间'xxx'中的'Class'。预期的可能元素列表: 命名空间'xxx'中的'容量'。
最后,这是XSD的一部分:
<xsd:element name="ClassA" minOccurs="0">
<xsd:complexType>
<xsd:all>
<xsd:element name="Physical" minOccurs="0">
<xsd:annotation>
<xsd:documentation>True, physical class A configuration</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Class" type="CabinClass.type" />
<xsd:element name="Capacity" type="Integer.ctype" nillable="true" />
</xsd:sequence>
<xsd:attributeGroup ref="Array.attgroup" />
</xsd:complexType>
</xsd:element>
<xsd:element name="Saleable" minOccurs="0">
<xsd:annotation>
<xsd:documentation>Class A configuration for sales purposes</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Class" type="CabinClass.type" />
<xsd:element name="Capacity" type="Integer.ctype" nillable="true" />
</xsd:sequence>
<xsd:attributeGroup ref="Array.attgroup" />
</xsd:complexType>
</xsd:element>
</xsd:all>
<xsd:attributeGroup ref="Container.attgroup" />
</xsd:complexType>
</xsd:element>
我的猜测是它与xsd:sequence的存在有关。但正如我所说,我不想修改由数据提供者提供的XSD,我们必须确保我们生成的XML完全兼容。
知道如何解决这个问题?
答案 0 :(得分:1)
简化代码可能是这样的:
public class Physical
{
[XmlElement("Capacity", typeof(int))]
[XmlElement("Class", typeof(string))]
public object[] Items { get; set; }
}
这将确保正确的反序列化,并按照它们在数组中的顺序给出元素的序列化。
工作版本可能如下所示:
public class Physical
{
[EditorBrowsable(EditorBrowsableState.Never)]
[XmlElement("Capacity", typeof(int))]
[XmlElement("Class", typeof(string))]
public object[] Items
{
get
{
object[] items = new object[Class.Length * 2];
for (int i = 0; i < items.Length; i += 2)
{
items[i] = Class[i / 2];
items[i + 1] = Capacity[i / 2];
}
return items;
}
set
{
Class = new string[value.Length / 2];
Capacity = new int[value.Length / 2];
for (int i = 0; i < value.Length; i += 2)
{
Class[i / 2] = (string)value[i];
Capacity[i / 2] = (int)value[i + 1];
}
}
}
[XmlIgnore]
public string[] Class { get; set; }
[XmlIgnore]
public int[] Capacity { get; set; }
}
将int
更改为Integerctype
,添加DataType
参数。
同样,改变第二节课。