XML De-serialize into type based on attribute

风流意气都作罢 提交于 2019-12-12 05:08:57

问题


I have the following Piece of XML:

<values>
<value type="A">
<something>ABC</something>
<something-else>DEF</something-else>
</value>
<value type="B">
<something-different>ABC</something-different>
<something-complex>
<id>B</id>
<name>B</name>
</something-complex>
</value>

How would I create the C# code to de-serialize this properly? Normally I'd do something like:

public class A
{
    [XmlElement("something")]
    public string Something { get; set; }
    [XmlElement("something-else")]
    public string SomethingElse { get; set; }    
}

and

public class B
{
    [XmlElement("something-different")]
    public string SomethingDifferent { get; set; }    
    [XmlElementAttribute("something-complex")]
    public B_ID SomethingComplex { get; set; }
}
public class B_ID
{
    [XmlElement("id")]
    public int ID { get; set; }
    [XmlElement("something-else")]
    public string Name { get; set; }    
}

But I have no idea how to use this based on an attribute when the elements have the same name but different content.


回答1:


You cannot do that with the standard attributes-based serialization, you will have to write your own code to parse the document and create objects accordingly.

Extremely simplified but working example:

using System.Xml;

class A {
    public string Something { get; set; }
}
class B {
    public string SomethingDifferent { get; set; }
}

class Program {

    const string xml = @"
<values>
  <value type='A'>
    <something>ABC</something>
  </value>
  <value type='B'>
    <something-different>ABC</something-different>
  </value>
</values>
";

    static void Main(string[] args) {

        XmlDocument doc = new XmlDocument();
        doc.LoadXml(xml);

        foreach (XmlNode node in doc.SelectNodes("/values/value")) {
            string type = node.Attributes["type"].Value;
            switch (type) { 
            case "A":
                A a = new A();
                foreach (XmlNode propertyNode in node.ChildNodes) {
                    switch (propertyNode.Name) {
                    case "something":
                        a.Something = propertyNode.InnerText;
                        break;
                    }
                }
                break;
            case "B":
                // etc ...
                break;
            }
        }

    }
}



回答2:


After a lot of thought, the easiest way to solve this, is to just do a quick text replace on the data to transform the XML into:

<values>
<value-a>
<something>ABC</something>
<something-else>DEF</something-else>
</value-a>
<value-b>
<something-different>ABC</something-different>
<something-complex>
<id>B</id>
<name>B</name>
</something-complex>
</value-b>


来源:https://stackoverflow.com/questions/9482354/xml-de-serialize-into-type-based-on-attribute

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!