0

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
4
  • What you mean by saying: deserialize xml with mutiple xml root? An *.xml file can have only one root node! Commented Sep 11, 2020 at 11:49
  • is there a way to deserialize xml with multiple residential elements and commercial elements with just one model which is PropertyList? Commented Sep 11, 2020 at 12:15
  • Show an xml example.| Yes, it is possible. Commented Sep 11, 2020 at 12:29
  • @AlexanderPetrov I have added the xml to my question Commented Sep 11, 2020 at 12:51

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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; }

     }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.