XML反序列化列表,对象只获得一个级别

时间:2015-06-09 15:59:59

标签: c# xml serialization

这与我在这里看到的许多问题类似,但它们都没有帮助或完全符合我的情况。我正在尝试将SQL Server的XML输出反序列化为C#对象。

我所拥有的类由一些属性和其他对象列表组成。问题是,当它反序列化时,它只抓取每个列表的第一项。

这是我的代码:

XML:

<Product>
  <Id>2</Id>
  <Name>Foo</Name>
  <Versions>
    <Version>
      <Id>2</Id>
      <Product>Foo</Product>
      <VersionNumber>2.0</VersionNumber>
      <Resources>
        <Resource>
          <Id>5</Id>
          <Name>FunTimes</Name>
          <Uri>/fun</Uri>
          <Properties>
            <Property>
              <Id>25</Id>
              <Name>Time</Name>
              <PropertyTypeId>5</PropertyTypeId>
              <EnumerationId>7</EnumerationId>
              <Enumeration>
                <Id>7</Id>
                <Name>Time</Name>
                <Members>
                  <Member>
                    <Name>Hours</Name>
                  </Member>
                  <Member>
                    <Name>Seconds</Name>
                  </Member>
                </Members>
              </Enumeration>
            </Property>
            <Property>
              <Id>58</Id>
              <Name>Place</Name>
              <PropertyTypeId>4</PropertyTypeId>
            </Property>
          </Properties>
        </Resource>
        <Resource>
          <Id>4</Id>
          <Name>BadTimes</Name>
          <Uri>/bad</Uri>
          <Properties>
            <Property>
              <Id>25</Id>
              <Name>Cause</Name>
              <PropertyTypeId>5</PropertyTypeId>
              <EnumerationId>7</EnumerationId>
              <Enumeration>
                <Id>7</Id>
                <Name>Cause</Name>
                <Members>
                  <Member>
                    <Name>Local</Name>
                  </Member>
                  <Member>
                    <Name>International</Name>
                  </Member>
                </Members>
              </Enumeration>
            </Property>
          </Properties>
        </Resource>
      </Resources>
    </Version>
  </Versions>
</Product>

我用来反序列化的代码:

XmlSerializer deserializer = new XmlSerializer(typeof(Product));
TextReader stringReader = new StringReader(content.ToString());
object obj = deserializer.Deserialize(stringReader);
Product XmlData = (Product) obj;
stringReader.Close();

其中XML存储在名为“content”的StringBuilder中。

以下是课程:

[Serializable]
public class Product
{
    // Fields...

    // Properties    
    [XmlElement]
    public int Id { get; set; }

    [XmlElement]
    public string Name { get; set; }

    [XmlElement]
    public string Comments { get; set; }

    [XmlArray("Versions")]
    [XmlArrayItem("Version")]
    public List<Version> Versions { get; set; }

    // Constructors and methods...
}

[Serializable]
public class Version
{
    // Fields...        

    // Properties
    [XmlElement]
    public int Id { get; set; }

    [XmlElement]
    public string Product { get; set; }

    [XmlElement]
    public string VersionNumber { get; set; }

    [XmlElement]
    public string Comments { get; set; }

    [XmlArray("Resources")]
    [XmlArrayItem("Resource")]
    public List<Resource> Resources { get; set; }

    // Constructors and methods...
}

[Serializable]
public class Resource
{
    // Fields...        

    // Properties
    [XmlElement]
    public int Id { get; set; }

    [XmlElement]
    public string Name { get; set; }

    [XmlElement]
    public string Uri { get; set; }

    [XmlElement]
    public string Comments { get; set; }

    [XmlArray("Properties")]
    [XmlArrayItem("Property")]
    public List<Property> Properties { get; set; }

    // Constructors and methods...
}

[Serializable]
public class Property
{
    // Fields...

    // Properties
    [XmlElement]
    public int Id { get; set; }

    [XmlElement]
    public string Name { get; set; }

    [XmlElement]
    public PropertyType PropertyTypeId { get; set; }

    [XmlElement]
    public int? MaximumStringLength { get; set; }

    [XmlElement]
    public double? MinimumValue { get; set; }

    [XmlElement]
    public double? MaximumValue { get; set; }

    [XmlElement]
    public int? EnumerationId { get; set; }

    [XmlElement]
    public PropertyEnumeration Enumeration { get; set; }

    [XmlElement]
    public int? ResourceId { get; set; }

    [XmlElement]
    public string Comments { get; set; }

    [XmlArray("Properties")]
    [XmlArrayItem("Property")]
    public List<Property> CompositeProperties { get; set; }

    // Constructors and methods...
}

如果我将它重新序列化为XML,那么结果是它给了我。 (我知道这不是重新序列化的错误。)

<?xml version="1.0" encoding="utf-16"?>
<Product xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Id>2</Id>
  <Name>Foo</Name>
  <Versions>
    <Version>
      <Id>2</Id>
      <Product>Foo</Product>
      <VersionNumber>2.0</VersionNumber>
      <Resources>
        <Resource>
          <Id>5</Id>
          <Name>FunTimes</Name>
          <Uri>/fun</Uri>
          <Properties>
            <Property>
              <Id>25</Id>
              <Name>Time</Name>
              <PropertyTypeId>5</PropertyTypeId>
              <MaximumStringLength xsi:nil="true" />
              <MinimumValue xsi:nil="true" />
              <MaximumValue xsi:nil="true" />
              <EnumerationId>7</EnumerationId>
              <Enumeration>
                <Id>7</Id>
                <Members>
                  <Member>Hours</Member>
                </Members>
              </Enumeration>
              <ResourceId xsi:nil="true" />
            </Property>
          </Properties>
        </Resource>
      </Resources>
    </Version>
  </Versions>
</Product>

还有一个Enumeration类和一些其他辅助类,但它们并不重要。基本上我需要它给我XML中的其余项目。我已经尝试使用列表属性使用XmlElement标记,但这会产生相同的结果。如何让它读取XML中的所有项目?

编辑:奥列格在评论中提到它对他有用。有谁知道我的系统是否有办法搞砸了它?

编辑:找到解决方案。我很遗憾甚至没有给你足够的信息来解决它。在XML中,它说

<Members>
  <Member>
    <Name>Local</Name>
  </Member>
  <Member>
    <Name>International</Name>
  </Member>
</Members>
<\ n>在枚举下。在我的Enumeration类中,我有一个属性,它是一个名为Members的字符串列表。它期待一个名单属性的成员列表,所以它吓坏了。通过将其更改为

<Members>
  <Member>Local</Member>
  <Member>International</Member>
</Members>

它解决了这个问题。

1 个答案:

答案 0 :(得分:0)

试试这个。我使用了一个文件,所以我更换了文本阅读器。您不需要两个级别的项目,如属性和属性。如果更改XML

,则可以消除一个级别
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XmlSerializer xs = new XmlSerializer(typeof(Product));
            XmlTextReader reader = new XmlTextReader(FILENAME);
            Product XML = (Product)xs.Deserialize(reader);
        }
    }
    [XmlRoot("Product")]
    public class Product
    {
        // Fields...

        // Properties    
        [XmlElement("Id")]
        public int Id { get; set; }

        [XmlElement("Name")]
        public string Name { get; set; }

        private string Comments { get; set; }

        [XmlElement("Versions")]
        public Versions Versions { get; set; }

        // Constructors and methods...
    }
    [XmlRoot("Versions")]
    public class Versions
    {
        [XmlElement("Version")]
        public List<Version> Version { get; set; }
    }

    [XmlRoot("Version")]
    public class Version
    {
        // Fields...        

        // Properties
        [XmlElement("Id")]
        public int Id { get; set; }

        [XmlElement("Product")]
        public string Product { get; set; }

        [XmlElement("VersionNumber")]
        public string VersionNumber { get; set; }

        [XmlElement("Comments")]
        public string Comments { get; set; }

        [XmlElement("Resources")]
        public Resources Resources { get; set; }

        // Constructors and methods...
    }

    [XmlRoot("Resourses")]
    public class Resources
    {
        [XmlElement("Resource")]
        public List<Resource> Resource { get; set; }
    }
    [XmlRoot("Resourse")]
    public class Resource
    {
        // Fields...        

        // Properties
        [XmlElement("Id")]
        public int Id { get; set; }

        [XmlElement("Name")]
        public string Name { get; set; }

        [XmlElement("Uri")]
        public string Uri { get; set; }

        private string Comments { get; set; }

        [XmlElement("Properties")]
        public Properties Properties { get; set; }
    }
        // Constructors and methods.
    [XmlRoot("Properties")]
    public class Properties
    {
        [XmlElement("Property")]
        public List<Property> properties { get; set; }
    }
    [XmlRoot("Property")]
    public class Property
    {
        // Fields...

        // Properties
        [XmlElement("Id")]
        public int Id { get; set; }

        [XmlElement("Name")]
        public string Name { get; set; }

        [XmlElement("PropertyTypeId")]
        public string PropertyTypeId { get; set; }

        private int? MaximumStringLength { get; set; }

        private double? MinimumValue { get; set; }

        private double? MaximumValue { get; set; }

        [XmlElement("EnumerationId")]
        public int? EnumerationId { get; set; }

        private int? ResourceId { get; set; }

        private string Comments { get; set; }

        [XmlElement("Enumeration")]
        public Enumeration Enumeration { get; set; }

        // Constructors and methods...
    }
    [XmlRoot("Enumeration")]
    public class Enumeration
    {
        [XmlElement("Id")]
        public int Id { get; set; }

        [XmlElement("Name")]
        public string Name { get; set; }

        [XmlElement("Members")]
        public Members Members { get; set; }
    }
    [XmlRoot("Members")]
    public class Members
    {
        [XmlElement("Member")]
        public List<Member> Member { get; set; }
    }
    [XmlRoot("Member")]
    public class Member
    {
        [XmlElement("Name")]
        public string Name { get; set; }
    }
}
​