[C#] 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 네임 스페이스가 필요하지 않습니다.



답변

컬렉션의 루트 요소 렌더링을 비활성화하려면 코드에서 속성 [XmlArrayItem][XmlElement]로 바꿔야합니다 .

xsixsd네임 스페이스 를 제거하려면 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>


답변

교체 [XmlArrayItem("VARIANT")]와 함께 [XmlElement("VARIANT")].


답변

기본 xml 직렬화 (속성 포함)를 사용하여이 요소를 제거 할 수 있다고 생각하지 않습니다. 이렇게 할 수 있다면 ShopItem클래스 를 직렬화 하면 허용되지 않는 객체에 대해 잘못된 형식의 xml (루트 요소 없음)이 생성됩니다.

그러나 할 수있는 일은 수동으로 구현하는 것 IXmlSerializable입니다. 이렇게하면 나중에 다시 세밀하게 제어 할 수 있습니다.

[ 편집 ]-죄송합니다. SHOPITEM이 아닌 변형을 제거하려했다고 잘못 읽었습니다. List “outer”요소를 제거하려면 [XmlArrayItem] 특성이 아닌 [XmlElement] 특성으로 표시하기 만하면됩니다. 이렇게하면 목록 항목이 목록을 외부 요소로 래핑하지 않고 지정된 요소 이름 만 사용하게됩니다.

네임 스페이스를 제거하기 위해 이것은 클래스의 마크 업이 아니라 seriliazer 자체에 의해 제어됩니다. 이 답변을 업데이트하는 동안 Rubens Farias가 네임 스페이스를 제거하는 방법을 보여주는 답변을 제공했습니다.


답변