Search code examples
c#xmlxmlserializer

Add element to an array


I have a class Person and an object which is a List<Person>.
This list is XML-serialized. The result is something like:

<?xml version="1.0" encoding="utf-16"?>
<ArrayOfPerson xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd... (etc)
  <Person>
    <Id>0</Id>
    <Name>Person 0</Name>
    <Birthday>2000-01-01T00:00:00</Birthday>
  </Person>
  <Person>
     ...
  </Person>
  <Person>
     ...
  </Person>
</ArrayOfPerson>

I want to add a new Person object to this List.

Using a XmlSerializer<List<Person>> I can Deserialize the complete XML to a List<Person> object, add my Person and Serialize it back to XML.

This seems to me a waste of processing power!

Is there a way I can add my Person without having to translate the XML text of all other person into Persons objects and translate them back to text?

I can use XElement to parse my XML to find my ArrayOfPerson and add one new XElement that contains my Person data. There are several answers here on SO that suggest this.

However, to create this XElement I have to enumerate the properties of the Person. get the values and add sub-elements to my XElement.

Is there some class of Method that can Create an XElement from an object, something like:

Person myPerson = ...
XElement xmlPerson = XElement.ToXml<Person>(myPerson);

Or do I have to write this myself?

Or maybe there is an even better method?


Solution

  • Use XML LINQ:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    using System.IO;
    
    namespace ConsoleApplication1
    {
        public class Program
        {
            const string FILENAME = @"c:\temp\test.xml";
            private static void Main()
            {
                StreamReader reader = new StreamReader(FILENAME);
                reader.ReadLine(); //skip the unicode encoding in the ident
    
                XDocument doc = XDocument.Load(reader);
                XElement arrayOfPerson = doc.Descendants("ArrayOfPerson").FirstOrDefault();
    
                arrayOfPerson.Add(new XElement("Person"), new object[] {
                    new XElement("Id", 0),
                    new XElement("Name", "Person 0"),
                    new XElement("Birthday", DateTime.Now.ToLongDateString()),
                });
            }
        }
    }