【问题标题】:XML Serialization - Disable rendering root element of arrayXML 序列化 - 禁用呈现数组的根元素
【发布时间】:2017-01-16 19:42:43
【问题描述】:

我可以以某种方式禁用集合根元素的呈现吗?

这个类带有序列化属性:

[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>

我不想在这里使用&lt;Variants&gt; 元素。我必须做什么?

我也不需要根元素中的 xsi 和 xsd 命名空间...

【问题讨论】:

标签: c# serialization attributes


【解决方案1】:

要禁用集合根元素的呈现,您必须在代码中将属性[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](如果存在)。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

    [编辑] - 抱歉 - 误读您试图删除变体,而不是 SHOPITEM。要删除 List“外部”元素,只需使用 [XmlElement] 属性而不是 [XmlArrayItem] 属性对其进行标记。这将导致列表条目仅使用指定的元素名称,而不将列表包装在外部元素中。

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

    【讨论】:

    • 哎呀 - 误读了您的帖子 - 以为您试图删除 SHOPITEM - 只是在编辑答案!
    猜你喜欢
    • 2015-04-25
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    • 1970-01-01
    相关资源
    最近更新 更多