2010-01-05 6 views
96

컬렉션의 루트 요소 렌더링을 어떻게해도 비활성화 할 수 있습니까? 직렬화와XML 직렬화 - 배열의 렌더링 루트 요소 사용 안 함

이 클래스는 속성 :

[XmlRoot(ElementName="SHOPITEM", Namespace="")] 
public class ShopItem 
{ 
    [XmlElement("PRODUCTNAME")] 
    public string ProductName { get; set; }  

    [XmlArrayItem("VARIANT")] 
    public List<ShopItem> Variants { get; set; } 
} 

이 XML을 생성합니다 : 여기 <Variants> 요소를 원하지 않는

<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> 

. 나는 무엇을해야만 하는가?

또한 나는

답변

151

컬렉션의 루트 요소 렌더링을 사용하지 않으려면 코드에서 [XmlArrayItem][XmlElement]으로 바꿔야합니다.

xsixsd 네임 스페이스를 제거하려면 비어있는 네임 스페이스가있는 XmlSerializerNamespaces 인스턴스를 만들고 개체를 serialize해야 할 때 전달하십시오.

이 예에서 살펴 보자 :
[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> 
+0

좋은 답변 ... – camainc

1

는 나는 (속성) 기본 XML 직렬화를 사용하여이 요소를 제거 할 수있다 생각하지 않습니다 ... 루트 요소에 XSI 및 XSD 네임 스페이스가 필요하지 않습니다. 이것을 할 수 있다면, ShopItem 클래스를 직렬화하면 객체에 대해 xml (루트 요소 없음)이 잘못 형성되어 허용되지 않습니다.

그러나 수행 할 수있는 작업은 수동으로 IXmlSerializable을 구현하는 것입니다. 이것은 당신에게 일종의 정교한 컨트롤을 제공 할 것입니다.

[편집] - 죄송합니다. SHOPITEM이 아니라 변형을 삭제하려고 시도 했으니까요. List "outer"요소를 제거하려면 [XmlArrayItem] 특성 대신 [XmlElement] 특성으로 표시하십시오. 이렇게하면 목록 요소가 외부 요소의 목록을 래핑하지 않고 지정된 요소 이름 만 사용하게됩니다.

네임 스페이스를 제거하는 데는 클래스의 마크 업이 아닌 seriliazer가 자체적으로 제어합니다. 방금이 답변을 업데이트하는 동안 Rubens Farias는 네임 스페이스를 제거하는 방법을 보여주는 답글을 제공했습니다.

+0

죄송합니다. 귀하의 게시물을 잘못 읽으 셨습니다. SHOPITEM을 (를) 제거하려고하신 것 같습니다. 답을 수정하는 것뿐입니다! –

28

[XmlElement("VARIANT")][XmlArrayItem("VARIANT")]를 교체합니다.