XmlSerializer生成错误的重复序列顺序

时间:2019-05-02 09:21:35

标签: c# xml xsd xml-serialization xsd.exe

当我在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: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? 或者,如果这只是Microsoft XmlSerializer的工作方式,我该如何修改C#类以获得正确的结果?

1 个答案:

答案 0 :(得分:0)

使用客户序列化工具:

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);
        }
    }
}