15

我正在尝试反序列化这个 xml 结构。

<?xml version="1.0"?>
<DietPlan>
    <Health>
        <Fruit>Test</Fruit>
        <Fruit>Test</Fruit>
        <Veggie>Test</Veggie>
        <Veggie>Test</Veggie>
    </Health>
</DietPlan>

我试过了:

[Serializable]
[XmlRoot(ElementName = "DietPlan")]
public class TestSerialization
{
    [XmlArray("Health")]
    [XmlArrayItem("Fruit")]
    public string[] Fruits { get; set; }

    [XmlArray("Health")]
    [XmlArrayItem("Veggie")]
    public string[] Veggie { get; set; }
}

但这会引发异常“XML 元素已存在于当前范围中。使用 XML 属性为元素指定另一个 XML 名称或命名空间。” 谢谢你的建议。

4

1 回答 1

30

您需要一个通用类型才能反序列化您的 XML,并且您可以使用[XmlElement]命名空间定义要根据元素名称实例化的类型,如下所示。

public class StackOverflow_15907357
{
    const string XML = @"<?xml version=""1.0""?>
                        <DietPlan>
                            <Health>
                                <Fruit>Test</Fruit>
                                <Fruit>Test</Fruit>
                                <Veggie>Test</Veggie>
                                <Veggie>Test</Veggie>
                            </Health>
                        </DietPlan>";

    [XmlRoot(ElementName = "DietPlan")]
    public class TestSerialization
    {
        [XmlArray("Health")]
        [XmlArrayItem("Fruit", Type = typeof(Fruit))]
        [XmlArrayItem("Veggie", Type = typeof(Veggie))]
        public Food[] Foods { get; set; }
    }

    [XmlInclude(typeof(Fruit))]
    [XmlInclude(typeof(Veggie))]
    public class Food
    {
        [XmlText]
        public string Text { get; set; }
    }

    public class Fruit : Food { }
    public class Veggie : Food { }

    public static void Test()
    {
        MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(XML));
        XmlSerializer xs = new XmlSerializer(typeof(TestSerialization));
        TestSerialization obj = (TestSerialization)xs.Deserialize(ms);
        foreach (var food in obj.Foods)
        {
            Console.WriteLine("{0}: {1}", food.GetType().Name, food.Text);
        }
    }
}
于 2013-04-10T07:01:36.310 回答