使用XDocument将不同类型的多个对象序列化为单个XML

时间:2014-12-23 20:58:53

标签: c# xml xml-serialization linq-to-xml

我正在尝试使用XDocument作为基础将对象列表序列化为XML。这样做的目的是在WCF服务中记录请求数据。

我的问题是如何获取对象的变量列表并将它们转换为XDocument?我能找到的所有例子都是如何为单个对象而不是对不同复杂类型的多个对象执行此操作。

我想要的输出是这样的:

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

最初我将其与其他Stackoverflow示例拼凑在一起,但我想改用XDocument。

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

我尝试使用herehere中的代码示例,但收到了错误。

我试过这个

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

1 个答案:

答案 0 :(得分:6)

看起来你几乎在尝试,下面应该会产生你想要的输出。基本上差异在于每个子对象都有很多XmlWriterXDocument,而只需要一个。

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