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. Щоб видалити "зовнішній" елемент "Список", просто позначте його атрибутом [XmlElement], а не атрибутом [XmlArrayItem]. Це призведе до того, що записи списку просто використовують вказане ім’я елемента, не загортаючи список у зовнішній елемент.

Для видалення просторів імен цим керує сам серіалізатор, а не розмітка на класі. Я щойно помітив, що, оновлюючи цю відповідь, Рубенс Фаріас надав відповідь, яка показує, як усунути простір імен.


oops - неправильно прочитав свою публікацію - думав, що ви намагаєтесь видалити SHOPITEM - просто редагування відповіді!
Роб Левін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.