Десериализация элементов последовательности XML C#.NET

Не нашел подходящей темы, а может не правильно искал. Прошу прощения, если на этот вопрос уже был дан ответ.

У меня есть следующий XSD

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink">
  <xs:element name="root" type="rootType" />
  <xs:complexType name="rootType">
    <xs:sequence>
      <xs:element name="innerElem1" maxOccurs="unbounded">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="innerElem2" maxOccurs="unbounded">
              <xs:complexType>
                <xs:sequence>
                  <xs:element name="innerElem3" maxOccurs="unbounded">
                    <xs:complexType>
                      <xs:simpleContent>
                        <xs:extension base="xs:string">
                          <xs:attribute name="name" type="xs:string" />
                        </xs:extension>
                      </xs:simpleContent>
                    </xs:complexType>
                  </xs:element>
                </xs:sequence>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
          <xs:attribute name="innerElem1Attr" type="xs:string" />
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

После использования инструмента xsd.exe он сгенерировал следующий класс

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.34209
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System.Xml.Serialization;

// 
// This source code was auto-generated by xsd, Version=4.0.30319.33440.
// 


/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlRootAttribute("root", Namespace="", IsNullable=false)]
public partial class rootType {

    private rootTypeInnerElem1[] innerElem1Field;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("innerElem1", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public rootTypeInnerElem1[] innerElem1 {
        get {
            return this.innerElem1Field;
        }
        set {
            this.innerElem1Field = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class rootTypeInnerElem1 {

    private rootTypeInnerElem1InnerElem2InnerElem3[][] innerElem2Field;

    private string innerElem1AttrField;

    /// <remarks/>
    [System.Xml.Serialization.XmlArrayAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    [System.Xml.Serialization.XmlArrayItemAttribute("innerElem3", typeof(rootTypeInnerElem1InnerElem2InnerElem3), Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=false)]
    public rootTypeInnerElem1InnerElem2InnerElem3[][] innerElem2 {
        get {
            return this.innerElem2Field;
        }
        set {
            this.innerElem2Field = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string innerElem1Attr {
        get {
            return this.innerElem1AttrField;
        }
        set {
            this.innerElem1AttrField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class rootTypeInnerElem1InnerElem2InnerElem3 {

    private string nameField;

    private string valueField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string name {
        get {
            return this.nameField;
        }
        set {
            this.nameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlTextAttribute()]
    public string Value {
        get {
            return this.valueField;
        }
        set {
            this.valueField = value;
        }
    }
}

Мне пришлось заменить двойной [][] на один, чтобы иметь возможность правильно десериализовать. Теперь, когда я пытаюсь десериализовать следующий XML

<root>
    <innerElem1 innerElem1Attr="attr1">
        <innerElem2>
            <innerElem3 name="name1">value1</innerElem3>
            <innerElem3 name="name2">value2</innerElem3>
            <innerElem3 name="name3">value3</innerElem3>
        </innerElem2>
        <innerElem2>
            <innerElem3 name="name4">value4</innerElem3>
            <innerElem3 name="name5">value5</innerElem3>
            <innerElem3 name="name6">value6</innerElem3>
        </innerElem2>
    </innerElem1>
</root>

У меня есть в моем объекте только последние 3 значения в моем массиве rootTypeInnerElem1InnerElem2InnerElem3.

Я использовал приведенный ниже код

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Xml;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                using (XmlReader xr = XmlReader.Create(@"C:\xmlfiletest.xml"))
                {
                    XmlSerializer xrc = new XmlSerializer(typeof(rootType));
                    var result = (rootType)xrc.Deserialize(xr);
                    Console.WriteLine("innerElem1: " + result.innerElem1.Count());
                    foreach (var elem1 in result.innerElem1)
                    {
                        Console.WriteLine("    innerElem2: " + elem1.innerElem2.Count());
                        foreach (var elem2 in elem1.innerElem2)
                        {
                            Console.WriteLine("        innerElemValue3: " + elem2.Value);
                        }
                    }
                }
                Console.ReadLine();
            }
            catch (Exception _ex)
            {
                Console.WriteLine(_ex.ToString());
            }
        }
    }
}

и на выходе значение4 значение5 значение6

Не могли бы вы сообщить мне, как следует изменить автоматически сгенерированный класс, чтобы в моем массиве были все 6 значений, а не только последние 3?

Большое спасибо.


person A Kalli    schedule 23.05.2015    source источник
comment
Я думаю, что такая проблема возникает, когда в XSD есть последовательность, которая содержит другую последовательность, а первая не имеет определенных атрибутов.   -  person A Kalli    schedule 23.05.2015


Ответы (1)


Отредактировал автоматически сгенерированный класс, как показано ниже, и теперь у меня есть правильно 2 последовательности массивов, и двойной цикл дает мне все значения.

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.34209
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System.Xml.Serialization;

// 
// This source code was auto-generated by xsd, Version=4.0.30319.33440.
// 


/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlRootAttribute("root", Namespace = "", IsNullable = false)]
public partial class rootType
{

    private rootTypeInnerElem1[] innerElem1Field;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("innerElem1", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public rootTypeInnerElem1[] innerElem1
    {
        get
        {
            return this.innerElem1Field;
        }
        set
        {
            this.innerElem1Field = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class rootTypeInnerElem1
{

    private rootTypeInnerElem1InnerElem2[] innerElem2Field;

    private string innerElem1AttrField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("innerElem2", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public rootTypeInnerElem1InnerElem2[] innerElem2
    {
        get
        {
            return this.innerElem2Field;
        }
        set
        {
            this.innerElem2Field = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string innerElem1Attr
    {
        get
        {
            return this.innerElem1AttrField;
        }
        set
        {
            this.innerElem1AttrField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class rootTypeInnerElem1InnerElem2
{

    private rootTypeInnerElem1InnerElem2InnerElem3[] innerElem3Field;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("innerElem3", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public rootTypeInnerElem1InnerElem2InnerElem3[] innerElem3
    {
        get
        {
            return this.innerElem3Field;
        }
        set
        {
            this.innerElem3Field = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class rootTypeInnerElem1InnerElem2InnerElem3
{

    private string nameField;

    private string valueField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string name
    {
        get
        {
            return this.nameField;
        }
        set
        {
            this.nameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlTextAttribute()]
    public string Value
    {
        get
        {
            return this.valueField;
        }
        set
        {
            this.valueField = value;
        }
    }
}
person A Kalli    schedule 23.05.2015