XMLシリアル化-配列のルート要素のレンダリングを無効にする


119

コレクションのルート要素のレンダリングを何らかの方法で無効にできますか?

シリアル化属性を持つこのクラス:

[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名前空間は必要ありません...


回答:


184

コレクションのルート要素のレンダリングを無効にするには、コードで属性[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>

[XmlArray]存在する場合も交換する必要があることに注意してください。
dbc


1

デフォルトのXMLシリアル化(属性付き)を使用してこの要素を削除することはできないと思います。これを実行できる場合、ShopItemクラスをシリアル化すると、オブジェクトのxmlの形式が正しくない(ルート要素がない)ことになり、これは許可されません。

ただし、できることは手動で実装することIXmlSerializableです。これにより、細かい制御ができるようになります。

[ 編集 ]-申し訳ありません-SHOPITEMではなく、バリアントを削除しようとしていたと誤解しています。リストの「外部」要素を削除するには、[XmlArrayItem]属性ではなく[XmlElement]属性でマークアップします。これにより、リストエントリは、リストを外側の要素でラップせずに、指定された要素名のみを使用するようになります。

名前空間を削除する場合、これはクラスのマークアップではなく、seriliazer自体によって制御されます。この回答を更新している間に、ルーベンスファリアスが名前空間を削除する方法を示す返信を提供していることに気づきました。


おっと-あなたの投稿を誤解-SHOPITEMを削除しようとしていると思った-答えを編集するだけ!
Rob Levine
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.