Сериализация XML - Отключить корневой элемент рендеринга массива
Можно ли каким-либо образом отключить рендеринг корневого элемента коллекции?
Этот класс с атрибутами сериализации:
[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 в корневом элементе...
Ответы
Ответ 1
Чтобы отключить рендеринг корневого элемента коллекции, вы должны заменить атрибут [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
Замените [XmlArrayItem("VARIANT")]
на [XmlElement("VARIANT")]
.
Ответ 3
Я не считаю, что этот элемент можно удалить, используя сериализацию xml по умолчанию (с атрибутами). Если бы вы могли это сделать, сериализация вашего класса ShopItem
привела бы к плохо сформированному xml (без корневого элемента) для объекта, который не разрешен.
Однако вы можете вручную реализовать IXmlSerializable
. Это даст вам вид мелкозернистого контроля над вами после.
[ Изменить] - извините - неправильно прочитал, что вы пытались удалить варианты, а не SHOPITEM. Чтобы удалить элемент "Внешний" списка, просто отметьте его атрибутом [XmlElement], а не атрибутом [XmlArrayItem]. Это приведет к тому, что записи в списке будут использовать только указанное имя элемента, без обертывания списка во внешнем элементе.
Для удаления пространств имен это контролируется самим seriliazer, а не разметкой класса.
Я только что заметил, что, хотя я обновил этот ответ, Rubens Farias предоставил ответ, который показывает вам, как устранить пространство имен.