Reputation: 229
Is it possible to deserialize xml with mutiple xml root?
If not, what is the best way to bind elements to a single model if it has the same properties on it?
Here are my codes:
[XmlRoot(ElementName = "residential")]
[XmlRoot(ElementName = "commercial")]
public class Property
{
[XmlElement(ElementName = "name")]
public string Name{ get; set; }
[XmlElement(ElementName = "description")]
public string Description { get; set; }
}
[XmlRoot(ElementName = "propertyList")]
public class PropertyList
{
[XmlChoiceIdentifier("EnumType")]
[XmlElement(ElementName = "residential")]
[XmlElement(ElementName = "commercial")]
[XmlElement(ElementName = "land")]
[XmlElement(ElementName = "rental")]
[XmlElement(ElementName = "holidayRental")]
[XmlElement(ElementName = "rural")]
public List<Property> Properties { get; set; }
[XmlIgnore]
public PropertyType[] EnumType;
[XmlAttribute(AttributeName = "date")]
public string Date { get; set; }
[XmlAttribute(AttributeName = "username")]
public string Username { get; set; }
[XmlAttribute(AttributeName = "password")]
public string Password { get; set; }
[XmlIgnore]
public string Type { get; set; }
}
[XmlType(IncludeInSchema = false)]
public enum PropertyType
{
residential,
commercial,
land,
rental,
holidayRental,
rural
}
var serializer = new XmlSerializer(typeof(Business.Models.PropertyList), new XmlRootAttribute("propertyList"));
I'm getting Object reference not set to an instance of an object error when trying to deserialize the XML.
Here's the sample xml
<propertyList date="2020-09-09T09:35:38" username="test" password="test">
<commercial modTime="2020-09-09T09:35:38" status="current">
<agentID>12345</agentID>
<uniqueID>12345</uniqueID>
</commercial>
<commercial modTime="2020-09-09T09:35:38" status="current">
<agentID>12345</agentID>
<uniqueID>12345</uniqueID>
</commercial>
<commercial modTime="2020-09-09T09:35:38" status="current">
<agentID>12345</agentID>
<uniqueID>12345</uniqueID>
</commercial>
<residentialmodTime="2020-09-09T09:35:38" status="current">
<agentID>12345</agentID>
<uniqueID>12345</uniqueID>
</residential>
<residentialmodTime="2020-09-09T09:35:38" status="current">
<agentID>12345</agentID>
<uniqueID>12345</uniqueID>
</residential>
<commercial modTime="2020-09-09T09:35:38" status="current">
<agentID>12345</agentID>
<uniqueID>12345</uniqueID>
</commercial>
</propertylist
Upvotes: 0
Views: 1574
Reputation: 34421
Use IXmlSerilizable with xml linq
sing System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Schema;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string INPUT_FILENAME = @"c:\temp\test.xml";
const string OUTPUT_FILENAME = @"c:\temp\test1.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(INPUT_FILENAME);
XmlSerializer serializer = new XmlSerializer(typeof(PropertyList));
PropertyList PropertyList = (PropertyList)serializer.Deserialize(reader);
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
XmlWriter writer = XmlWriter.Create(OUTPUT_FILENAME, settings);
serializer.Serialize(writer, PropertyList);
}
}
public enum PropertyType
{
residential,
commercial,
land,
rental,
holidayRental,
rural
}
public class Property
{
public PropertyType propertyType { get; set; }
public DateTime Date { get; set; }
public string status { get; set; }
[XmlElement(ElementName = "agentID")]
public string agentID { get; set; }
[XmlElement(ElementName = "uniqueID")]
public string uniqueID { get; set; }
}
[XmlRoot(ElementName = "propertyList")]
public class PropertyList : IXmlSerializable
{
public List<Property> Properties { get; set; }
// Constructors
public PropertyList()
{
Properties = new List<Property>();
}
// Xml Serialization Infrastructure
public void WriteXml(XmlWriter writer)
{
XElement propertyList = new XElement("propertyList");
propertyList.Add(new XAttribute("date", Date.ToString("yyyy-MM-ddTHH:mm:ss")));
propertyList.Add(new XAttribute("username", Username));
propertyList.Add(new XAttribute("password", Password));
foreach (Property xProperty in Properties)
{
XElement property = new XElement(xProperty.propertyType.ToString(), new object[] {
new XAttribute("modTime", xProperty.Date.ToString("yyyy-MM-ddTHH:mm:ss")),
new XAttribute("status", xProperty.status),
new XElement("agentID", xProperty.agentID),
new XElement("uniqueID", xProperty.uniqueID)
});
propertyList.Add(property);
}
propertyList.WriteTo(writer);
}
public void ReadXml(XmlReader reader)
{
XElement element = (XElement)XElement.ReadFrom(reader);
Date = (DateTime)element.Attribute("date");
Username = (string)element.Attribute("username");
Password = (string)element.Attribute("password");
foreach (XElement xProperty in element.Elements())
{
Property property = new Property()
{
propertyType = (PropertyType)Enum.Parse(typeof(PropertyType), xProperty.Name.LocalName),
Date = (DateTime)xProperty.Attribute("modTime"),
status = (string)xProperty.Attribute("status"),
agentID = (string)xProperty.Element("agentID"),
uniqueID = (string)xProperty.Element("uniqueID")
};
Properties.Add(property);
}
}
public XmlSchema GetSchema()
{
return (null);
}
public DateTime Date { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
}
Upvotes: 1
Reputation: 14231
Reading can be implemented as follows
var settings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment };
var list = new List<PropertyList>();
using (var xmlReader = XmlReader.Create("test.xml", settings))
{
while (xmlReader.MoveToContent() == XmlNodeType.Element)
{
list.Add((PropertyList)serializer.Deserialize(xmlReader));
}
}
Each xml fragment is deserialized separately and added to the list.
Upvotes: 1