![](/img/trans.png)
[英]Add additional elements from a dictionary to the XML during serialization in C#
[英]How to alternate XML Elements during XML serialization in C#?
我有一個由數據提供者提供給我們的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>
正如您所看到的,Physical和Sealable的子元素是備用的(即Class,然后是Capacity,然后是Class,然后是Capacity等)。
這是由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完全兼容。
不知道怎樣才能解決這個問題?
簡化的代碼可能是這樣的:
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
參數。
同樣,更改第二個類。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.