XML序列化 - 禁用数组根元素的渲染

136

我能否以某种方式禁用集合根元素的渲染?

这个类带有序列化属性:

[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 命名空间...


https://learn.microsoft.com/en-us/dotnet/standard/serialization/controlling-xml-serialization-using-attributes#serializing-an-array-as-a-sequence-of-elements - Iman
3个回答

217
为了禁用集合根元素的呈现,您必须在代码中将属性[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>

请注意,如果存在 [XmlArray],也必须进行替换。 - dbc

35

[XmlArrayItem("VARIANT")] 替换为 [XmlElement("VARIANT")]


0

我不相信使用默认的xml序列化(带有属性)可以删除此元素。如果您这样做,那么序列化ShopItem类将导致对象的格式不正确的xml(没有根元素),这是不允许的。

但是,您可以手动实现IXmlSerializable。这将为您提供所需的细粒度控制。

[编辑] - 抱歉 - 误读了您试图删除Variants而不是SHOPITEM。要删除列表“outer”元素,只需使用[XmlElement]属性标记它,而不是[XmlArrayItem]属性。这将使列表条目仅使用指定的元素名称,而无需在外部元素中包装列表。

要删除命名空间,这由序列化器本身控制,而不是类上的标记。我刚刚注意到,虽然我已更新了此答案,但Rubens Farias已经提供了一个回复,向您展示如何消除命名空间。


抱歉,我误读了您的帖子 - 以为您想要删除SHOPITEM - 我正在编辑答案! - Rob Levine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接