代码之家  ›  专栏  ›  技术社区  ›  Jan Remunda

XML序列化-禁用呈现数组的根元素

  •  106
  • Jan Remunda  · 技术社区  · 15 年前

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

    具有序列化属性的此类:

    [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名称空间…

    3 回复  |  直到 8 年前
        1
  •  165
  •   Rubens Farias    8 年前

    若要禁用集合根元素的呈现,必须替换属性 [XmlArrayItem] 具有 [XmlElement] 在您的代码中。

    用于移除 xsi xsd 命名空间,创建一个 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>
    
        2
  •  31
  •   Pent Ploompuu    15 年前

    替换 [XmlArrayItem("VARIANT")] 具有 [XmlElement("VARIANT")] .

        3
  •  1
  •   Rob Levine    15 年前

    我认为不可能使用默认的XML序列化(带有属性)删除此元素。如果你能做到这一点,那么将你的 ShopItem 类将导致对象的XML格式错误(没有根元素),这是不允许的。

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

    [ 编辑 ]-抱歉-误读到您试图删除变体,而不是ShopItem。要删除列表“outer”元素,只需用[xmlElement]属性而不是[xmlArrayItem]属性标记它。这将导致列表项只使用指定的元素名称,而不将列表包装在外部元素中。

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