将XML反序列化为对象时缺失子节点

7

我有一个处理特定xml的要求,但在反序列化其中的对象列表时遇到了问题。以下是xml:

<catalog>
<item>
    <id>18338517</id>
    <note label="Name ">Gear xyz</note>
    <note label="Size ">10</note>       
    <note label="Source">Store xyz</note>
    <relation weight="100">
        <type>External</type>
        <id>123</id>
        <name>Mcday</name>          
    </relation>
    <relation weight="99">
        <type>Internal</type>
        <id>234</id>
        <name>Mcnight</name>
    </relation>
</item>
    <item> ..... </item></catalog>

以下是我的类:
[XmlRoot("catalog")]
public class Catalog
{
    [XmlArray("item")]
    [XmlArrayItem("item", typeof(Item))]
    public Item[] item{ get; set; }
}

[XmlRoot("item")]
public class Item
{
    [XmlElement("id")]
    public string id { get; set; }

    [XmlArrayItem("note", typeof(Note))]
    public Note[] note { get; set; }

    [XmlArrayItem("relation", typeof(Relation))]
    public Relation[] relation { get; set; }
}

[Serializable]
public class Note
{
    [XmlAttribute("label")]
    public string label { get; set; }

    [XmlText]
    public string Value { get; set; }
}

[Serializable]
public class Relation
{
    [XmlAttribute("weight")]
    public string weight { get; set; }

    [XmlText]
    public string Value { get; set; }

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

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

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

最后,调用反序列化。
Catalog catalog = null;
XmlSerializer mySerializer = new XmlSerializer(typeof(Catalog));
using (TextReader reader = new StreamReader(@"D:\TEMP\deserialize xml\catalog.xml"))
{
    catalog = (Catalog)mySerializer.Deserialize(reader);
}

它没有返回任何错误,只是目录对象中的空项目。
2个回答

7

要使用XmlArrayXmlArrayItem属性,就像您在此处所做的那样:

[XmlArray("term")]
[XmlArrayItem("term", typeof(Item))]
public Item[] item{ get; set; }

您的XML必须提供正确的集合元素。因此,您的类应如下所示

[XmlRoot("catalog")]
public class Catalog
{
    [XmlArray("items")] // note that I corrected 'term' to 'items'/'item'
    [XmlArrayItem("item", typeof(Item))]
    public Item[] item{ get; set; }
}

你的XML应该看起来像这样:

和你的XML应该长成这样

<catalog>
  <items>
    <item>
      <id>18338517</id>
       ...

请注意<items>元素对应[XmlArray("items")],以及子元素<item>对应[XmlArrayItem("item", typeof(Item))]
如果您不想/不能更改XML格式,可以简单地使用XmlElement属性而不是XmlArrayItem属性。因此,您的最终代码应该如下所示:
[XmlRoot("catalog")]
public class Catalog
{
     [XmlElement("item")] // no XmlArray/XmlArrayItem, just XmlElement
     public Item[] Items { get; set; }
}

[XmlType("item")]
public class Item
{
    [XmlElement("id")]
    public string id { get; set; }

    [XmlElement("note", typeof(Note))] // no XmlArray/XmlArrayItem, just XmlElement
    public Note[] note { get; set; }

    [XmlElement("relation", typeof(Relation))] // no XmlArray/XmlArrayItem, just XmlElement
    public Relation[] relation { get; set; }
}

[Serializable]
public class Note
{
    [XmlAttribute("label")]
    public string label { get; set; }

    [XmlText]
    public string Value { get; set; }
}

[Serializable]
public class Relation
{
    [XmlAttribute("weight")]
    public string weight { get; set; }

    [XmlText]
    public string Value { get; set; }

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

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

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

我尝试更改类,结果就像魔术一样:) 非常感谢您的帮助。 - Cornelis Tjendra

3
您的属性有误:
public class Catalog
{
    [XmlArray("term")]
    [XmlArrayItem("term", typeof(Item))]

请改用以下方法:

public class Catalog
{
    [XmlArray("items")]
    [XmlArrayItem("item", typeof(Item))]
编辑:针对您项目的进一步开发,您应该考虑创建一个XML模式,并使用例如XSD.exe生成代码,详情请参见此问题:在C#中将XML反序列化为对象编辑2:查看MSDN文档,XmlArrayAttribute构造函数定义如下:
public XmlArrayAttribute(
    string elementName
)

参数文档如下:

elementName Type: System.String

The name of the XML element that the XmlSerializer generates.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接