Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deserializing a List of a:anyType

I have an existing XML file provided by another application, that looks similar to this:

<Root xmlns="http://someNameSpace">
    <DisplayName>RootName</DisplayName>
    <Groups>
        <Group>
            <Elements>
                <a:anyType i:type="SomeType">
                    <DisplayName>ElementName</DisplayName>
                </a>
            </Elements>
        </Group>
    </Groups>
</Root>

I'm attempting to write a class that can be deserialized with XmlSerializer, which currently looks like this:

public class Root
{
    public string DisplayName { get; set; }
    public List<Group> Groups { get; set; }
}

public class Group : SomeType
{
    public List<SomeType> Elements { get; set; }
}

public class SomeType
{
    public string DisplayName { get; set; }
}

And simple deserialization code using XmlSerializer:

var serializer = new XmlSerializer(typeof (Root));
using (var streamReader = new StreamReader(somePathToXmlFile))
{
    root = (Root) serializer.Deserialize(streamReader);
}

Everything is deserializing ok, except for the Elements list - it is always empty. I've tried adorning the Elements property in Group with XmlAttributes in the following ways:

  1. [XmlArrayItem(ElementName = "a")]
  2. [XmlArrayItem(ElementName = "a:anyType")]
  3. [XmlArrayItem(ElementName = "a", Type = typeof(SomeType))]
  4. [XmlArrayItem(ElementName = "a:anyType", Type = typeof(SomeType))]

So far, nothing has worked.

Does anyone know the correct way to get the <a:anyType i:type="SomeType"> items to deserialize into the Elements list?

Edit I've since realised I left out of my question was that the <Root> actually had a namespace: <Root xmlns="http://someNameSpace">. See XML above.

like image 925
Phillip Parker Avatar asked Nov 28 '25 13:11

Phillip Parker


1 Answers

Considering you xml with added namespace declartions on Root

<Root xmlns:a="http://custom/a" xmlns:i="http://custom/i">
<DisplayName>RootName</DisplayName>
<Groups>
    <Group>
        <Elements>
          <a:anyType i:type="SomeType">
            <DisplayName>ElementName</DisplayName>
          </a:anyType>           
        </Elements>
    </Group>
</Groups>
</Root>

I've succeeded in deserializing it using following xml attributes:

public class Group : SomeType
{

    [XmlArrayItem(typeof(SomeType),ElementName = "anyType", Namespace = "http://custom/a")]
    public List<SomeType> Elements { get; set; }
}

public class SomeType
{
    [XmlElement(typeof(string),ElementName="DisplayName",Namespace="")]
    public string DisplayName { get; set; }
}

Or if you cannot add namespace declarations to xml use XmlNamespaceManager

var serializer = new XmlSerializer(typeof(Root));
        var nameTable = new NameTable();
        var namespaceManager = new XmlNamespaceManager(nameTable);
        namespaceManager.AddNamespace("a", "http://custom/a");
        namespaceManager.AddNamespace("i", "http://custom/i");
        var parserContext = new XmlParserContext(null, namespaceManager, null, XmlSpace.None);
        var settings = new XmlReaderSettings()
        {
            ConformanceLevel = ConformanceLevel.Fragment

        };
        using(var fileStream=File.OpenRead(somePathToXmlFile))
        {
            using(var reader=XmlReader.Create(fileStream,settings,parserContext))
            {
                var root = (Root)serializer.Deserialize(reader);
            }
        }
like image 117
Dima Korn Avatar answered Dec 01 '25 03:12

Dima Korn