开发者

XML Serialization - Disable rendering root element of array

Can I somehow disable rendering of root element of collection?

This class with serialization attributes:

[XmlRoot(ElementName="SHOPITEM", Namespace="")]
public class ShopItem
{
    [XmlElement("PRODUCTNAME")]
    public string ProductName { get; set; }       
    
    [XmlArrayItem("VARIANT")]
    public List<ShopItem> Variants { get; set; }
}

generates this XML:

<SHOPITEM xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd=&开发者_如何学Pythonquot;http://www.w3.org/2001/XMLSchema">
      <PRODUCTNAME>test</PRODUCTNAME>
      <Variants>
          <VARIANT>
              <PRODUCTNAME>hi 1</PRODUCTNAME>
          </VARIANT>
          <VARIANT>
              <PRODUCTNAME>hi 2</PRODUCTNAME>
          </VARIANT>           
      </Variants>        
</SHOPITEM>

I don't want <Variants> element here. What must I do?

Also I don't need xsi and xsd namespaces in root element...


To disable rendering of root element of collection, you must replace the attribute [XmlArrayItem] with [XmlElement] in your code.

For removing the xsi and xsd namespaces, create an XmlSerializerNamespaces instance with an empty namespace and pass it when you need to serialize your object.

Take a look on this example:

[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

I got this output:

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


Replace [XmlArrayItem("VARIANT")] with [XmlElement("VARIANT")].


I don't believe it is possible to remove this element using the default xml serialization (with attributes). If you could do this, then serializing your ShopItem class would result in badly formed xml (no root element) for the object, which is not allowed.

What you can do however, is manually implement IXmlSerializable. This will give you the sort of fine-grained control you a re after.

[Edit] - sorry - misread that you were trying to remove Variants, not SHOPITEM. To remove the List "outer" element, just mark it up with an [XmlElement] attribute rather than an [XmlArrayItem] attribute. This will cause the list entries to just use the specified element name, without wrapping the list in an outer element.

For removing the namespaces, this is controlled by the seriliazer itself, not the markup on the class. I've just noticed that while I've updated this answer, Rubens Farias has provided an reply that shows you how to eliminate the namespace.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜