XmlSerializer 生成错误顺序的重复序列
Posted
技术标签:
【中文标题】XmlSerializer 生成错误顺序的重复序列【英文标题】:XmlSerializer generates wrong order of repeated sequence 【发布时间】:2019-09-20 18:58:09 【问题描述】:当我在xsd:sequence
上有中继器时
例如:<xsd:sequence minOccurs="1" maxOccurs="unbounded">
这将是匹配的 xml:
<Element>
<name>e1</name>
<number>n1</number>
<details>i1</details>
<name>e2</name>
<number>n2</number>
<details>i2</details>
<name>e3</name>
<number>n3</number>
<details>i3</details>
</Element>
另一方面,当我在元素上有一个中继器时:
<xsd:sequence>
<xsd:element name="name" type="xsd:token" minOccurs="1" maxOccurs="unbounded"/>
<xsd:element name="number" type="xsd:token" minOccurs="1" maxOccurs="unbounded"/>
<xsd:element name="details" type="xsd:token" minOccurs="1" maxOccurs="unbounded"/>
</xsd:sequence>
匹配的 xml 将是:
<Element>
<name>e1</name>
<name>e2</name>
<name>e3</name>
<number>n1</number>
<number>n2</number>
<number>n3</number>
<details>i1</details>
<details>i2</details>
<details>i3</details>
</Element>
但是当我将以下 xsd 文件转换为 C# 类时(使用 xsd.exe)
<xsd:element name="Element" type="ElementType"/>
<xsd:complexType name="ElementType">
<xsd:sequence minOccurs="1" maxOccurs="unbounded">
<xsd:element name="name" type="xsd:token"/>
<xsd:element name="number" type="xsd:token"/>
<xsd:element name="details" type="xsd:token"/>
</xsd:sequence>
</xsd:complexType>
生成的 C# 类:
public partial class ElementType
private string[] nameField;
private string[] numberField;
private string[] detailsField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("name", DataType="token")]
public string[] name
get
return this.nameField;
set
this.nameField= value;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("number", DataType="token")]
public string[] number
get
return this.numberField;
set
this.numberField = value;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("details", DataType="token")]
public string[] details
get
return this.detailsField;
set
this.detailsField= value;
我得到了这个 xml(基于 XmlSerializer
的类生成)
<Element>
<name>e1</name>
<name>e2</name>
<name>e3</name>
<number>n1</number>
<number>n2</number>
<number>n3</number>
<details>i1</details>
<details>i2</details>
<details>i3</details>
</Element>
有没有办法生成正确的xml?
或者如果这只是微软XmlSerializer
的工作方式,我需要如何修改 C# 类以获得正确的结果?
【问题讨论】:
微软按照类中属性的顺序进行序列化。因此,如果您有一个数组 string[] 名称,则 xml 中的名称数组将按顺序出现。 @jdweng 我明白了,但这是我在这里的固定要求。所以我的问题是:有没有办法得到预期的结果?可能没有办法编辑生成的 XML ......因为我猜 C# 中没有等效的元素可以做到这一点。 【参考方案1】:使用客户序列化器:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Linq;
using System.Xml.Schema;
namespace ConsoleApplication111
class Program
const string INPUT_FILENAME = @"c:\temp\test.xml";
const string OUTPUT_FILENAME = @"c:\temp\test1.xml";
static void Main(string[] args)
XmlReader reader = XmlReader.Create(INPUT_FILENAME);
XmlSerializer serializer = new XmlSerializer(typeof(ElementType));
ElementType elementType = (ElementType)serializer.Deserialize(reader);
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
XmlWriter writer = XmlWriter.Create (OUTPUT_FILENAME, settings);
serializer.Serialize(writer, elementType);
[XmlRoot("Element")]
public partial class ElementType : IXmlSerializable
private string[] nameField;
private string[] numberField;
private string[] detailsField;
/// <remarks/>
[XmlElement(ElementName = "name", DataType = "token")]
public string[] name
get
return this.nameField;
set
this.nameField = value;
/// <remarks/>
[XmlElement(ElementName = "number", DataType = "token")]
public string[] number
get
return this.numberField;
set
this.numberField = value;
/// <remarks/>
[XmlElement(ElementName = "details", DataType = "token")]
public string[] details
get
return this.detailsField;
set
this.detailsField = value;
public void ReadXml(XmlReader reader)
XElement elementType = XElement.Load(reader);
nameField = elementType.Elements("name").Select(x => (string)x).ToArray();
numberField = elementType.Elements("number").Select(x => (string)x).ToArray();
detailsField = elementType.Elements("details").Select(x => (string)x).ToArray();
public void WriteXml(XmlWriter writer)
int count = nameField.Count();
XElement element = new XElement("Element");
for(int i = 0; i < count; i++)
element.Add(new XElement("name", name[i]));
element.Add(new XElement("number", number[i]));
element.Add(new XElement("details", detailsField[i]));
writer.WriteRaw(element.ToString());
public XmlSchema GetSchema()
return (null);
【讨论】:
以上是关于XmlSerializer 生成错误顺序的重复序列的主要内容,如果未能解决你的问题,请参考以下文章
C# XMLSerializer 将错误的类型反序列化为 List
无法使用 c# xmlserializer 反序列化以前序列化的 XML