How to include multiple XML files in a single XML file for deserialization by XmlSerializer in .NET

Posted by harrydev on Stack Overflow See other posts from Stack Overflow or by harrydev
Published on 2010-02-12T13:50:32Z Indexed on 2010/04/02 20:03 UTC
Read the original article Hit count: 447

Filed under:
|
|
|

Hi, is it possible to use the XmlSerializer in .NET to load an XML file which includes other XML files? And how?

This, in order to share XML state easily in two "parent" XML files, e.g. AB and BC in below.

Example:

using System;
using System.IO;
using System.Xml.Serialization;

namespace XmlSerializerMultipleFilesTest
{
    [Serializable]
    public class A
    {
        public int Value
        { get; set; }
    }

    [Serializable]
    public class B
    {
        public double Value
        { get; set; }
    }

    [Serializable]
    public class C
    {
        public string Value
        { get; set; }
    }

    [Serializable]
    public class AB
    {
        public A A
        { get; set; }
        public B B
        { get; set; }
    }

    [Serializable]
    public class BC
    {
        public B B
        { get; set; }
        public C C
        { get; set; }
    }

    class Program
    {
        public static void Serialize<T>(T data, string filePath)
        {
            using (var writer = new StreamWriter(filePath))
            {
                var xmlSerializer = new XmlSerializer(typeof(T));
                xmlSerializer.Serialize(writer, data);
            }
        }
        public static T Deserialize<T>(string filePath)
        {
            using (var reader = new StreamReader(filePath))
            {
                var xmlSerializer = new XmlSerializer(typeof(T));
                return (T)xmlSerializer.Deserialize(reader);
            }
        }

        static void Main(string[] args)
        {
            const string fileNameA = @"A.xml";
            const string fileNameB = @"B.xml";
            const string fileNameC = @"C.xml";

            const string fileNameAB = @"AB.xml";
            const string fileNameBC = @"BC.xml";

            var a = new A(){ Value = 42 };
            var b = new B(){ Value = Math.PI };
            var c = new C(){ Value = "Something rotten" };

            Serialize(a, fileNameA);
            Serialize(b, fileNameB);
            Serialize(c, fileNameC);

            // How can AB and BC be deserialized from single 
            // files which include two of the A, B or C files.
            // Using ideally something like:
            var ab = Deserialize<AB>(fileNameAB);
            var bc = Deserialize<BC>(fileNameBC);
            // That is, so that A, B, C xml file 
            // contents are shared across these two
        }
    }
}

Thus, the A, B, C files contain the following:

A.xml:

<?xml version="1.0" encoding="utf-8"?>
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Value>42</Value>
</A>

B.xml:

<?xml version="1.0" encoding="utf-8"?>
<B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Value>3.1415926535897931</Value>
</B>

C.xml:

<?xml version="1.0" encoding="utf-8"?>
<C xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Value>Something rotten</Value>
</C>

And then the "parent" XML files would contain a XML include file of some sort (I have not been able to find anything like this), such as:

AB.xml:

<?xml version="1.0" encoding="utf-8"?>
<AB xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <A include="A.xml"/>
  <B include="B.xml"/>
</AB>

BC.xml:

<?xml version="1.0" encoding="utf-8"?>
<BC xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <B include="B.xml"/>
  <C include="C.xml"/>
</BC>

Of course, I guess this can be solved by implementing IXmlSerializer for AB and BC, but I was hoping there was an easier solution or a generic solution with which classes themselves only need the [Serializable] attribute and nothing else. That is, the split into multiple files is XML only and handled by XmlSerializer itself or a custom generic serializer on top of this.

I know this should be somewhat possible with app.config (as in http://stackoverflow.com/questions/480538/use-xml-includes-or-config-references-in-app-config-to-include-other-config-files), but I would prefer a solution based on XmlSerializer.

Thanks.

© Stack Overflow or respective owner

Related posts about xml-serialization

Related posts about .net-3.5