Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serialize multiple objects of different types into single XML using XDocument

I am trying to serialize a list of objects into XML using XDocument as the base. The purpose of this is to log request data inside a WCF service.

My question is how can I take a variable list of objects and convert them into an XDocument? All the examples I could find were how to do this for a single object and not for multiple objects of different complex types.

My desired output is something like this:

<rootElementName>
    <CustomObjectType1>
        <SubData1>Test</SubData1>
        <SubData2>2014-12-22T16:33:00</SubData2>
    </CustomObjectType1>
    <CustomObjectType2>
        <SubData3>123456</SubDataType2>
    </CustomObjectType2>
</rootElementName>

Originally I pieced this together from other Stackoverflow examples, but I want to use XDocument instead.

private static XmlDocument CreateXmlFromObjects(string rootElementName, params object[] inputs)
{
    var doc = new XmlDocument();
    var root = doc.AppendChild(doc.CreateElement(rootElementName));

    doc.DocumentElement.SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
    doc.DocumentElement.SetAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");

    foreach(var input in inputs)
    {
        SerializeAppend(doc, input);
    }

    return doc;
}

private static void SerializeAppend(XmlNode parentNode, object obj)
{
    XPathNavigator nav = parentNode.CreateNavigator();
    using (var writer = nav.AppendChild())
    {
        var serializer = new XmlSerializer(obj.GetType());
        writer.WriteWhitespace("");
        serializer.Serialize(writer, obj);
        writer.Close();
    }
}

I tried using the code example from here and here, but was getting errors.

I tried this

private static XDocument CreateXmlFromObjects(string rootElementName, params object[] inputs)
{
    var doc = new XDocument();
    doc.Add(new XElement(rootElementName, inputs.Select(x => SerializeAppend2(x))));

    return doc;
}

private static XDocument SerializeAppend2(object obj)
{
    var document = new XDocument();
    using (var writer = document.CreateWriter())
    {
        var serializer = new XmlSerializer(obj.GetType());
        serializer.Serialize(writer, obj);
    }

    return document;
}
like image 596
merekel Avatar asked Mar 18 '23 13:03

merekel


1 Answers

It looks like you are almost there with your attempt, below should generate your desired output. Basically the difference is instead of having many XmlWriter and XDocument for each sub object, you only need one.

private static XDocument CreateXmlFromObjects(string rootElementName, params object[] inputs)
{
    var doc = new XDocument();
    using (XmlWriter writer = doc.CreateWriter())
    {
        writer.WriteStartElement(rootElementName);                
        foreach (var input in inputs)
            new XmlSerializer(input.GetType()).Serialize(writer, input);
        writer.WriteEndElement();
    }

    return doc;
}
like image 191
steve16351 Avatar answered Apr 06 '23 06:04

steve16351