如何在C#中的XML序列化过程中交替使用XML元素?
我有一个数据提供者提供给我们的XSD模式。我不能修改它。我使用XSD.exe命令行工具生成了这些类。对于一切完美的工作,我可以用C#创建我的对象,用XML序列化它,并用XSD验证它 我有一小部分问题。预期产出为:如何在C#中的XML序列化过程中交替使用XML元素?,c#,xml,serialization,xsd,C#,Xml,Serialization,Xsd,我有一个数据提供者提供给我们的XSD模式。我不能修改它。我使用XSD.exe命令行工具生成了这些类。对于一切完美的工作,我可以用C#创建我的对象,用XML序列化它,并用XSD验证它 我有一小部分问题。预期产出为: <Physical> <Class>P</Class> <Capacity>14</Capacity> <Class>J</Class>
<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>
在验证过程中,无论是否使用Order属性,我都会收到如下错误:
命名空间“xxx”中的元素“Physical”具有无效的子元素
命名空间“xxx”中的“类”。预期可能的要素清单:
命名空间“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>
正确,物理A类配置
用于销售目的的A类配置
我猜想这与xsd:sequence的存在有关。但正如我所说,我不想修改XSD,因为它是由数据提供者提供的,我们必须确保生成的XML完全兼容
知道如何解决这个问题吗?简化的代码可能是:
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; }
}
公共类物理
{
[EditorBrowsable(EditorBrowsableState.Never)]
[XmlElement(“容量”,类型(int))]
[XmlElement(“类”,类型(字符串))]
公共对象[]项
{
得到
{
object[]items=新对象[Class.Length*2];
对于(int i=0;i
将int
更改为integertype
,添加DataType
参数
类似地,更改第二个类。顺序与xml没有区别,但由于模式问题,因此在您的情况下,顺序非常重要。确保顺序的最佳方法是使用XDocument或XmlDocument方法编写自定义序列化。您也可以使用XmlWriter。@jdweng,谢谢您的输入。是的,他们期望这些元素有一个精确的顺序,这是很奇怪的,但不幸的是事实就是如此。对于我们来说,自定义序列化程序可能不是最好的选择,因为XSD和生成的XML文件非常庞大。我们正在尝试使用标准序列化,并仅在为简单起见需要时自定义XSD.exe生成的类。如果文件很大,则使用标准序列化会出现内存不足错误。所以您必须使用XmlReader。别无选择。
<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>
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; }
}