Simon
Simon

Reputation: 4794

How can I deserialize any xml element to a list via the XmlSerializer?

I want to deserialize the following xml document:

<?xml version="1.0" encoding="utf-8"?>
<ExtensionFileTypes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Group>
    <Item1>value 1</Item1>
    <Item2>value 2</Item2>
    <Item3>value 3</Item3>
    [ more items ... ]
  </Group>
</ExtensionFileTypes>

This document should be parsed to the following c# class:

public class ExtensionFileTypes
{
    [XmlArrayItem("Item*")]
    public List<string> Group = new List<string>();
}

The wildcard in the parameter of the class attribute [XmlArrayItem("Item*")] demonstrates what I want to archive: pass the xml elements <Item*> to my c# list.

I use the XmlSerializer to deserialize the xml-document:

public static void ReadXML(string pFilename)
{
    XmlSerializer lXmlSerializer = new XmlSerializer(typeof(ExtensionFileTypes));

    lXmlSerializer.UnknownElement += new XmlElementEventHandler(XmlSerializer_UnknownNode);

    FileStream lFileStream = new FileStream(pFilename, FileMode.Open);
    ExtensionFileTypes lExtensionFileTypes = (ExtensionFileTypes)lXmlSerializer.Deserialize(lFileStream);

    var lFoo = lExtensionFileTypes; // 0 Items in Group
}

Problem: lFoo contains 0 <Item*> elements:

enter image description here

How can I get these elements?

Upvotes: 0

Views: 791

Answers (1)

Sergii Zhevzhyk
Sergii Zhevzhyk

Reputation: 4202

Unfortunately, the ElementName cannot contain a wildcard. If the number of Item elements is limited, for example, only Item1, Item2, Item3, then you could apply the XmlArrayItem attribute multiple times. If the number of Item elements is large you could process a document in advance using Regex to change all Item* tags to Item:

string updatedXmlString = Regex.Replace(xmlString, "<(/?)Item[0-9]+>", "<$1Item>");

Now you can simply write:

public class ExtensionFileTypes
{
    [XmlArrayItem("Item")]
    public List<string> Group = new List<string>();
}

If you cannot apply preprocessing to the xml then you could always parse it manually or implement the IXmlSerializable interface.

Upvotes: 1

Related Questions