序列化两个具有相同名称但不同子节点的节点

时间:2011-01-11 23:36:46

标签: c# xml-serialization

我需要能够定义两个具有相同名称但完全不同的子节点结构的节点。我没有设计这个XML模式,但暂时我不得不按原样使用它。我意识到这是对XML所有内容的可怕滥用,但你有它。

我需要它看起来像:

<order>
    <ItemType type="Clubs">
        <Club num="1">
            <ClubName>Some Name</ClubName>
            <ClubChoice>Something Else</ClubChoice>
        </Club>
    </ItemType>
    <ItemType type="Gift" val="MailGreeting">
        <GiftName>MailGreeting</GiftName>
        <GiftDescription></GiftDescription>
        <GiftQuanity>1</GiftQuanity>
    </ItemType
</order>

当然,它比你得到的要点复杂得多。

我正在使用XmlSerializer并且非常希望避免使用XDocument,但如果这就是我需要做的事情,那就这样吧。

1 个答案:

答案 0 :(得分:5)

如果您的订单包含属性而不是列表,您可以告诉序列化程序为这些元素命名:

[XmlRoot("order")]
public class Order
{
    private Whatever whateverInstance;
    [XmlElement("ItemType")]
    public Whatever WhateverInstance
    {
        get { return whateverInstance; }
        set { whateverInstance = value; }
    }

    private Something somethingInstance;
    [XmlElement("ItemType")]
    public Something SomethingInstance
    {
        get { return somethingInstance; }
        set { somethingInstance = value; }
    }
}

如果它是一个列表,你可以得到一个相同的元素名称,但你会得到一个冗余的xsi:Type属性:

[XmlRoot("order")]
public class Order
{
    private ItemType[] itemTypes;
    [XmlElement("ItemType")]
    public ItemType[] ItemTypes
    {
        get { return itemTypes; }
        set { itemTypes = value; }
    }
}

[XmlInclude(typeof(Clubs))]
[XmlInclude(typeof(Gift))]
public abstract class ItemType
{
    private string type = "None";
    [XmlAttribute]
    public string Type
    {
        get { return type; }
        set { type = value; }
    }
}

public class Clubs : ItemType
{
    public Clubs()
    {
        Type = "Clubs";
    }

    private Club[] clubsArray;
    [XmlElement("Club")]
    public Club[] ClubsArray
    {
        get { return clubsArray; }
        set { clubsArray = value; }
    }

}

public class Club
{
    private int num = 0;
    [XmlAttribute("num")]
    public int Num
    {
        get { return num; }
        set { num = value; }
    }

    private string clubName = "";
    public string ClubName
    {
        get { return clubName; }
        set { clubName = value; }
    }

    private string clubChoice = "";
    public string ClubChoice
    {
        get { return clubChoice; }
        set { clubChoice = value; }
    }
}

public class Gift : ItemType
{
    public Gift()
    {
        Type = "Gift";
    }

    private string val = "";
    [XmlAttribute("val")]
    public string Val
    {
        get { return val; }
        set { val = value; }
    }

    private string giftName = "";
    public string GiftName
    {
        get { return giftName; }
        set { giftName = value; }
    }

    private string giftDescription = "";
    public string GiftDescription
    {
        get { return giftDescription; }
        set { giftDescription = value; }
    }

    private int giftQuanity = 0;
    public int GiftQuanity
    {
        get { return giftQuanity; }
        set { giftQuanity = value; }
    }
}

测试:

        List<ItemType> list = new List<ItemType>();
        list.Add(new Clubs() { ClubsArray = new Club[] { new Club() { Num = 0, ClubName = "Some Name", ClubChoice = "Something Else" } } });
        list.Add(new Gift() { Val = "MailGreeting", GiftName = "MailGreeting", GiftDescription = "GiftDescription", GiftQuanity = 1});
        Order order = new Order();
        rder.ItemTypes = list.ToArray();

        XmlSerializer serializer = new XmlSerializer(typeof(Order));
        StreamWriter sw = new StreamWriter(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\Stuff.xml");
        serializer.Serialize(sw, order);
        sw.Close();

输出:

<order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ItemType xsi:type="Clubs" Type="Clubs">
    <Club num="0">
      <ClubName>Some Name</ClubName>
      <ClubChoice>Something Else</ClubChoice>
    </Club>
  </ItemType>
  <ItemType xsi:type="Gift" Type="Gift" val="MailGreeting">
    <GiftName>MailGreeting</GiftName>
    <GiftDescription>GiftDescription</GiftDescription>
    <GiftQuanity>1</GiftQuanity>
  </ItemType>
</order>