Сериализация двух узлов с одинаковым именем, но разными дочерними узлами - PullRequest
2 голосов
/ 12 января 2011

Мне нужно иметь возможность определять два узла с одинаковым именем, но совершенно разными структурами подузлов.Я не проектировал эту 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 Ответ

5 голосов
/ 12 января 2011

Если ваш заказ содержит свойства, а не список, вы можете указать сериализатору назвать элементы следующим образом:

[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>
...