Reputation: 43
Hi I have the following Xml to deserialize:
<RootNode>
<Item
Name="Bill"
Age="34"
Job="Lorry Driver"
Married="Yes" />
<Item
FavouriteColour="Blue"
Age="12"
<Item
Job="Librarian"
/>
</RootNote>
How can I deserialize the Item element with a list of attribute key value pairs when I dont know the key names or how many attributes there will be?
Upvotes: 1
Views: 2691
Reputation: 116534
You can use the XmlAnyAttribute
attribute to specify that arbitrary attributes will be serialized and deserialized into an XmlAttribute []
property or field when using XmlSerializer
.
For instance, if you want to represent your attributes as a Dictionary<string, string>
, you could define your Item
and RootNode
classes as follows, using a proxy XmlAttribute[]
property to convert the dictionary from and to the required XmlAttribute
array:
public class Item
{
[XmlIgnore]
public Dictionary<string, string> Attributes { get; set; }
[XmlAnyAttribute]
public XmlAttribute[] XmlAttributes
{
get
{
if (Attributes == null)
return null;
var doc = new XmlDocument();
return Attributes.Select(p => { var a = doc.CreateAttribute(p.Key); a.Value = p.Value; return a; }).ToArray();
}
set
{
if (value == null)
Attributes = null;
else
Attributes = value.ToDictionary(a => a.Name, a => a.Value);
}
}
}
public class RootNode
{
[XmlElement("Item")]
public List<Item> Items { get; set; }
}
Prototype fiddle.
Upvotes: 1
Reputation: 153
Using XmlDocument
class you can just select the "Item" nodes and iterate through the attributes:
string myXml = "<RootNode><Item Name=\"Bill\" Age=\"34\" Job=\"Lorry Driver\" Married=\"Yes\" /><Item FavouriteColour=\"Blue\" Age=\"12\" /><Item Job=\"Librarian\" /></RootNode>"
XmlDocument doc = new XmlDocument();
doc.LoadXml(myXml);
XmlNodeList itemNodes = doc.SelectNodes("RootNode/Item");
foreach(XmlNode node in itemNodes)
{
XmlAttributeCollection attributes = node.Attributes;
foreach(XmlAttribute attr in attributes)
{
// Do something...
}
}
Or, if you want an object containing only the Attributes as List of KeyValuePairs, you could use something like:
var items = from XmlNode node in itemNodes
select new
{
Attributes = (from XmlAttribute attr in node.Attributes
select new KeyValuePair<string, string>(attr.Name, attr.Value)).ToList()
};
Upvotes: 0