2017-11-10 84 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