XmlSerializer генерирует неправильный порядок повторения последовательности - PullRequest
1 голос
/ 02 мая 2019

Когда у меня есть повторитель на 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 голосов
/ 03 мая 2019

Используйте Serialzier клиента:

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