1

I have some XML in the following format:

<PurchaseItem>
    <Name>Item 1</Name>
    <Costs>
        <Cost>
            <Code>A</Code>
            <Info>Test 1</Info>
        </Cost>
        <Cost>
            <Code>B</Code>
            <Info>Test 1</Info>
        </Cost>
        <Cost>
            <Code>C</Code>
            <Info>Test 1</Info>
        </Cost>
    </Costs>
</PurchaseItem>

I want this XML to deserialize into the following class:

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

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

public class Cost
{
    [XmlElement("Code")]
    public string Code{ get; set; }

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

However I cannot seem to get this to work unless I make another class to be a wrapper for the Cost[]. How can I have the cost array be serialized in the PurchaseItem class as in the code above?

4

2 回答 2

3

您正在定义一个数组,您应该使用该[XmlArray]属性:)

[Serializable]
public class Cost
{
    [XmlElement("Code")]
    public string Code { get; set; }

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

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

    // XmlArray of Cost
    [XmlArray(ElementName = "Costs")]
    public Cost[] Costs { get; set; }
}

public class Tests
{

    [Test]
    public void Test()
    {
        var serializer = new XmlSerializer(typeof (PurchaseItem));

        var xml = @"<PurchaseItem>
                        <Name>Item 1</Name>
                        <Costs>
                            <Cost>
                                <Code>A</Code>
                                <Info>Test 1</Info>
                            </Cost>
                            <Cost>
                                <Code>B</Code>
                                <Info>Test 1</Info>
                            </Cost>
                            <Cost>
                                <Code>C</Code>
                                <Info>Test 1</Info>
                            </Cost>
                        </Costs>
                    </PurchaseItem>";

        var data = Encoding.UTF8.GetBytes(xml);
        var reader = XmlReader.Create(new MemoryStream(data));
        var item = (PurchaseItem) serializer.Deserialize(reader);

        Assert.AreEqual(item.Costs[0].Code, "A");
        Assert.AreEqual(item.Costs[1].Code, "B");
        Assert.AreEqual(item.Costs[2].Code, "C");
    }

}
于 2013-06-04T09:46:45.663 回答
2

那是因为您已经[XmlElement]在 Costs 数组上设置了属性。在任何情况下,您都应该将属性[XmlArray]与数组或集合元素一起使用。例如,这使您可以更改生成的 XML 中集合元素的名称。(有关XmlArray 属性的更多信息在这里)

但是,序列化程序无需任何属性即可提供您正在寻找的功能。有这个类:

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

    public Cost[] Costs { get; set; }
}

将为您提供以下 XML:

<?xml version="1.0" encoding="utf-16"?>
<PurchaseItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name>Foo</Name>
  <Costs>
    <Cost>
      <Code>C#</Code>
      <Info>Awesome</Info>
    </Cost>
    <Cost>
      <Code>VB6</Code>
      <Info>:(</Info>
    </Cost>
  </Costs>
</PurchaseItem>

只有当您想更改该集合的生成方式时,您才需要添加一个[XmlArray]属性。例如,如果您希望将包含成本元素的节点命名为“FooCosts”,那么您需要:

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

    [XmlArray("FooCosts")]
    public Cost[] Costs { get; set; }
}

<?xml version="1.0" encoding="utf-16"?>
<PurchaseItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name>Foo</Name>
  <FooCosts>
    <Cost>
      <Code>C#</Code>
      <Info>Awesome</Info>
    </Cost>
    <Cost>
      <Code>VB6</Code>
      <Info>:(</Info>
    </Cost>
  </FooCosts>
</PurchaseItem>
于 2013-06-04T09:46:51.153 回答