动态插入或更新XMLRoot元素

时间:2017-11-10 21:36:53

标签: c# xml xmlserializer

我在XMLRoot上有一个类,在数组上有一个XMLElement。基于客户端,当我序列化我的类时,我必须更改XMLRoot和XMLElement。有没有办法动态地改变它

[XmlRoot("sample")]
public class MyData
{
    private ArrayList map;

    public MyData()
    {
        map = new ArrayList();
    }

    [XmlElement("url")]
    public Location[] Locations
    {
        get
        {
            Location[] items = new Location[map.Count];
            map.CopyTo(items);
            return items;
        }

        set
        {
            if (value == null)
                return;
            Location[] items = (Location[])value;
            map.Clear();
            foreach (Location item in items)
                map.Add(item);
        }
    }

    public int Add(Location item)
    {
        return map.Add(item);
    }
}

正如您所看到的,我的根源是"示例",基于客户端,它可以是" sample"或"保留"。 XMLElement是" url"并且基于客户端,它可以是" url"或" dataitem"

我使用XMLSerializer序列化

// My condition needs to be here to determine which 
// root and xmlelement should use
var xs = new XmlSerializer(typeof(MyData));
var oString = new StringWriterWithEncoding(Encoding.UTF8);

提前致谢

1 个答案:

答案 0 :(得分:1)

请参阅MSDN-Overrides on XmlSerializer

您可以通过构造函数提供Overrides - 最好阅读doku。

示例:

using System.Collections;
using System.Linq;
using System.Xml;
using System.Xml.Serialization;

public class Location
{
    public string L;
}

[XmlRoot("sample")]
public class MyData
{
    public MyData()
    {
        map = new ArrayList();
    }

    [XmlElement("url")]
    public Location[] Locations
    {
        get
        {
            Location[] items = new Location[map.Count];
            map.CopyTo(items);
            return items;
        }

        set
        {
            if (value == null)
                return;
            Location[] items = (Location[])value;
            map.Clear();
            foreach (Location item in items)
                map.Add(item);
        }
    }

    public int Add(Location item)
    {
        return map.Add(item);
    }

    private ArrayList map;
}

internal class Program
{

Xml打印到屏幕:

    private static void DoSerialize(MyData m, XmlSerializer xs)
    {
        var settings = new XmlWriterSettings();
        settings.OmitXmlDeclaration = true;
        settings.Indent = true;
        settings.NewLineOnAttributes = true;

        var sww = new System.IO.StringWriter();
        XmlWriter writer = XmlWriter.Create(sww, settings);
        xs.Serialize(writer, m);
        Console.WriteLine(sww.ToString().Replace("><", ">\r\n<"));
    }

使用重载的构造函数:

    static void Main()
    {
        // testdata
        MyData m = new MyData 
        { 
            Locations = new Location[2] 
            { 
                new Location { L = "L1" }, 
                new Location { L = "L2" } 
            } 
        };

        // simple Serializer
        var xs = new XmlSerializer(typeof(MyData));

        DoSerialize(m, xs);
        Console.WriteLine();


        var xs2 = new XmlSerializer(typeof(MyData), XmlAttributeOverride(),
                     new Type[] { typeof(Location[]) }, RootOverride(), "");

        DoSerialize(m, xs2);

        Console.ReadLine();
    }

    // override the root node
    private static XmlRootAttribute RootOverride() => new XmlRootAttribute("OtherName");

    // override your Languages property
    private static XmlAttributeOverrides XmlAttributeOverride()
    {
        var attrs = new XmlAttributes();
        attrs.XmlElements.Add(new XmlElementAttribute("Location"));

        var o = new XmlAttributeOverrides();
        o.Add(typeof(MyData), "Locations", attrs);
        return o;
    }
}

<强>输出:

<sample xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://
www.w3.org/2001/XMLSchema">
  <url>
    <L>L1</L>
  </url>
  <url>
    <L>L2</L>
  </url>
</sample>

<OtherName xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http
://www.w3.org/2001/XMLSchema">
  <Location>
    <L>L1</L>
  </Location>
  <Location>
    <L>L2</L>
  </Location>
</OtherName>