2017-11-10 83 views
1

我有一个XMLRoot类和一个XMLElement数组。基于客户端,当我序列化我的课程时,我必须更改XMLRoot和XMLElement。有没有办法来动态动态插入或更新XMLRoot元素

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

改变它,你可以看到,我的根是“样品”的基础上,客户端也可以是“样品”或“保留”。的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

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打印到屏幕:

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

输出::

重载的构造的

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

用法

<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> 
+0

它几乎按照您的解决方案工作。只有我现在有问题的是我得到的xmlns声明在级别,我不想 – jvm

+0

创建一个新的SO问题并提供详细信息。我很高兴得到赞扬或接受的答案。 –

+0

我收到了<?xml version =“1.0”encoding =“utf-8”?> https://www.domaincom/url html的 总是 2017-09-11T04:50:27Z jvm