在根元素中使用XmlSerializer和数组

40

我有一个类似以下的XML文档:

<scan_details>
    <object name="C:\Users\MyUser\Documents\Target1.doc">
        ...
    </object>
    <object name="C:\Users\MyUser\Documents\Target2.doc">
        ...
    </object>
    ...
</scan_details>

我希望使用System.Xml.Serialization属性来简化XML反序列化。我的问题是我不知道如何指定根节点包含一个数组。

我尝试创建了以下类:

[XmlRoot("scan_details")]
public class ScanDetails
{
    [XmlArray("object")]
    public ScanDetail[] Items { get; set; }
}

public class ScanDetail
{
    [XmlAttribute("name")]
    public string Filename { get; set; }
}

然而,当我将XML反序列化为ScanDetails对象时,Items数组仍然保持为null

如何反序列化根节点中的数组?

1个回答

75

您应该使用 [XmlElement],而不是 [XmlArray] 来修饰Items属性 - 它已经是一个数组了,您只需要设置元素名称。

public class StackOverflow_12924221
{
    [XmlRoot("scan_details")]
    public class ScanDetails
    {
        [XmlElement("object")]
        public ScanDetail[] Items { get; set; }
    }

    public class ScanDetail
    {
        [XmlAttribute("name")]
        public string Filename { get; set; }
    }

    const string XML = @"<scan_details> 
                            <object name=""C:\Users\MyUser\Documents\Target1.doc""> 
                            </object> 
                            <object name=""C:\Users\MyUser\Documents\Target2.doc""> 
                            </object> 
                        </scan_details> ";

    public static void Test()
    {
        XmlSerializer xs = new XmlSerializer(typeof(ScanDetails));
        MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(XML));
        var obj = xs.Deserialize(ms) as ScanDetails;
        foreach (var sd in obj.Items)
        {
            Console.WriteLine(sd.Filename);
        }
    }
}

1
啊...他们使用的术语很令人困惑。我一直在关注XmlArrayXmlArrayItem。谢谢! - Hand-E-Food
1
如果一个数组不仅仅是在根级别下,那么数组属性似乎仍然需要[XmlArray("arrayElementName")],而不是[XmlElement("arrayElementItemName")],但如果像你的答案一样在根级别下,它需要[XmlElement("arrayElementItemName")],你知道为什么吗?就好像在根级别下,您正在描述内部重复元素类型,而在其他地方则是数组类型。 - CRice
我想花一点时间感谢你。我在许多问题的答案中搜寻,这是唯一有效的方法。它非常不直观,你不需要在根元素或数组元素上定义数组属性。 - Gaugeforever
如果元素包含的子元素都是相同类型或者派生自相同类型,则可以使用XmlElement。如果元素包含多个不相关类型的集合,则需要使用XmlArray,以便为每个集合创建一个子元素。这是XML的细节,您不能在同一集合中拥有不相关的类型,属性只是反映了这一点。 - Tamir Daniely

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