Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polymorphic element typenames using XmlInclude..?

I want to create a structure like:

<root>
 <items>
  <myns:a s="a"/>
  <b s="a"/>
 </items>
</root>

Where the items in root are descendant from a common base class. I just cannot get it working. The following snippet creates

<root>
 <items>
  <Base xsi:type="A" s="a"/>
  <Base xsi:type="B" s="a"/>
 </items>
</root>

[Serializable]
[XmlInclude(typeof(A))]
[XmlInclude(typeof(B))]
public class Base
{
}

[Serializable]
public class A : Base
{
    public string a = "a";
}

[Serializable]
public class B : Base
{
    public string b = "b";
}

[Serializable]
public class Root
{
    public List<Base> items = new List<Base>();
}

If I use the XmlType attribute, I can change the xsi:type name, but not the name tag. I also want to use a custom namespace on one of the tags, but if I add Namespace to XmlType, I get an error message saying that the type cannot be found, and XmlInclude has to be added..

I guess this is actually quite simple, I just couldn't find out how..

like image 796
simendsjo Avatar asked Feb 13 '26 12:02

simendsjo


1 Answers

Are you looking for XmlArrayItemAttribute?

[Serializable]
public class Root
{
    [XmlArrayItem("a", typeof(A), Namespace = "myns")]
    [XmlArrayItem("b", typeof(B))]
    public List<Base> items = new List<Base>();
}

This will serialize as:

<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <items>
    <a xmlns="myns">
      <a>a</a>
    </a>
    <b>
      <b>b</b>
    </b>
  </items>
</Root>

You could also use XmlElementAttribute if you want the items to be direct children of Root instead of having an element for items.

like image 164
Quartermeister Avatar answered Feb 16 '26 03:02

Quartermeister