2010-01-05 57 views
96

我可以以某種方式禁止渲染根元素的集合嗎?XML序列化 - 禁用陣列的渲染根元素

該類系列化屬性:

[XmlRoot(ElementName="SHOPITEM", Namespace="")] 
public class ShopItem 
{ 
    [XmlElement("PRODUCTNAME")] 
    public string ProductName { get; set; }  

    [XmlArrayItem("VARIANT")] 
    public List<ShopItem> Variants { get; set; } 
} 

生成此XML:

<SHOPITEM xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
     <PRODUCTNAME>test</PRODUCTNAME> 
     <Variants> 
      <VARIANT> 
       <PRODUCTNAME>hi 1</PRODUCTNAME> 
      </VARIANT> 
      <VARIANT> 
       <PRODUCTNAME>hi 2</PRODUCTNAME> 
      </VARIANT>   
     </Variants>   
</SHOPITEM> 

我不想在這裏<Variants>元素。我必須做什麼?

而且我不需要XSI和XSD命名空間中的根元素...

回答

151

要禁止呈現收集的根元素,您必須在代碼中將屬性[XmlArrayItem]替換爲[XmlElement]

要刪除xsixsd名稱空間,請創建一個空名稱空間的XmlSerializerNamespaces實例,並在需要序列化對象時傳遞它。

看看這個例子:

[XmlRoot("SHOPITEM")] 
public class ShopItem 
{ 
    [XmlElement("PRODUCTNAME")] 
    public string ProductName { get; set; } 

    [XmlElement("VARIANT")] // was [XmlArrayItem] 
    public List<ShopItem> Variants { get; set; } 
} 

// ... 

ShopItem item = new ShopItem() 
{ 
    ProductName = "test", 
    Variants = new List<ShopItem>() 
    { 
     new ShopItem{ ProductName = "hi 1" }, 
     new ShopItem{ ProductName = "hi 2" } 
    } 
}; 

// This will remove the xsi/xsd namespaces from serialization 
XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); 
ns.Add("", ""); 

XmlSerializer ser = new XmlSerializer(typeof(ShopItem)); 
ser.Serialize(Console.Out, item, ns); // Inform the XmlSerializerNamespaces here 

我得到這樣的輸出:

<?xml version="1.0" encoding="ibm850"?> 
<SHOPITEM> 
    <PRODUCTNAME>test</PRODUCTNAME> 
    <VARIANT> 
    <PRODUCTNAME>hi 1</PRODUCTNAME> 
    </VARIANT> 
    <VARIANT> 
    <PRODUCTNAME>hi 2</PRODUCTNAME> 
    </VARIANT> 
</SHOPITEM> 
+0

好答案... – camainc 2017-01-24 17:21:35

1

我不相信這是可能的,除去使用默認XML序列化(帶屬性)這個元素。如果你能做到這一點,那麼序列化你的ShopItem類將導致該對象嚴重形成XML(無根元素),這是不允許的。

然而,你可以做什麼,是手動執行IXmlSerializable。這會給你以後的細節控制。

[編輯] - 抱歉 - 誤讀您嘗試刪除變體而非SHOPITEM。要刪除List「outer」元素,只需將它標記爲[XmlElement]屬性而不是[XmlArrayItem]屬性即可。這將導致列表條目只使用指定的元素名稱,而不將該列表包裹在外部元素中。

對於刪除命名空間,這是由seriliazer本身控制的,而不是類的標記。 我剛剛注意到,雖然我已經更新了這個答案,但Rubens Farias提供了一個回覆,告訴你如何消除命名空間。

+0

oops - 誤讀你的文章 - 以爲你試圖刪除SHOPITEM - 只需編輯答案! – 2010-01-05 14:23:00

28

更換[XmlArrayItem("VARIANT")][XmlElement("VARIANT")]