简体   繁体   中英

Custom XML Serialization adding extra attributes

I have the following class.

public class ConfigurationItem
{
    public String Type { get; set; }
    public String Value { get; set; }
}

This code performs the serialization.

static void Main(string[] args)
{
    List<ConfigurationItem> cis = new List<ConfigurationItem>();
    cis.Add(new ConfigurationItem() { Type = "Car", Value = "Car Value" });
    cis.Add(new ConfigurationItem() { Type = "Bike", Value = "Bike Value" });

    System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(cis.GetType());
    x.Serialize(Console.Out, cis);
}

The actual output is below.

<?xml version="1.0" encoding="IBM437"?>
<ArrayOfConfigurationItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <ConfigurationItem>
        <Type>Car</Type>
        <Value>Car Value</Value>
    </ConfigurationItem>
    <ConfigurationItem>
        <Type>Bike</Type>
        <Value>Bike Value</Value>        
    </ConfigurationItem>
</ArrayOfConfigurationItem>

I would like to produce the following XML.

<?xml version="1.0" encoding="IBM437"?>
<ArrayOfConfigurationItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <ConfigurationItem>
        <Type>Car</Type>
        <Value Label="Car Label">Car Value</Value>
    </ConfigurationItem>
    <ConfigurationItem>
        <Type>Bike</Type>
        <Value Label="Bike Label">Bike Value</Value>        
    </ConfigurationItem>
</ArrayOfConfigurationItem>

I have following type to Label mapping table available

Dictionary<String, String> ValueLabels = new Dictionary<string, string>()
{
    {"Car","Car Label"},
    {"Bike","Bike Label"}
};

I can't touch the ConfigurationItem class. Is it possible to use System.Xml.Serialization.XmlAttributeOverrides or something similar?

Edit 1 I have an ugly solution that I'm using now. I'm using normal serialization and adding data to the XmlDocument manually.

static void Main(string[] args)
{
    List<ConfigurationItem> cis = new List<ConfigurationItem>();
    cis.Add(new ConfigurationItem(){Type = "Car", Value = "Car Value"});
    cis.Add(new ConfigurationItem(){Type = "Bike", Value = "Bike Value"});

    Dictionary<String, String> valueLabels = new Dictionary<string, string>()
    {
        {"Car","Car Label"},
        {"Bike","Bike Label"}
    };

    var detailDocument = new System.Xml.XmlDocument();
    var nav = detailDocument.CreateNavigator();

    if (nav != null)
    {
        using (System.Xml.XmlWriter w = nav.AppendChild())
        {
            var ser = new System.Xml.Serialization.XmlSerializer(cis.GetType());
            ser.Serialize(w, cis);
        }
    }
    var nodeList = detailDocument.DocumentElement.SelectNodes("//ConfigurationItem");
    foreach (System.Xml.XmlNode node in nodeList)
    {
        String type = ((System.Xml.XmlElement)node.SelectNodes("Type")[0]).InnerText;
        ((System.Xml.XmlElement)node.SelectNodes("Value")[0]).SetAttribute("Label", valueLabels[type]);
    }

    System.Xml.XmlTextWriter writer = new System.Xml.XmlTextWriter(Console.Out);
    writer.Formatting = System.Xml.Formatting.Indented;
    detailDocument.WriteTo(writer);            

    Console.ReadLine();
}

Still looking for better solution...

If you want to output an attribute, you'll need a property which will be serialized as the attribute. Try the following:

public class ConfigurationItem
{
    public String Type { get; set; }
    public String Value { get; set; }
    [XmlAttribute("Label")]
    public string Label
    {
        get {return Value;}
        set {Value = value;}
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM