2010-04-19 6 views
10

C#에서 XML 직렬화를 사용하는 경우 XmlNode에 입력 된 XML의 일부를 deserialize하고 싶습니다.XmlNode로 요소를 deserialize하는 방법은 무엇입니까?

그래서,이 XML을 제공 :

<Thing Name="George"> 
    <Document> 
    <subnode1/> 
    <subnode2/> 
    </Document> 
</Thing> 

내가하는 XMLNode에 문서 요소를 직렬화하는.

다음은 위의 XML에서 'Document'요소가 아닌 'subnode1'요소로 Document를 설정 한 것입니다.

Document 속성을 Document 요소로 설정하는 코드는 어떻게 얻을 수 있습니까? 나는 것은 인스턴스에 위의 XML을 역 직렬화 할 XmlSerializer를 사용할 때

using System; 
using System.IO; 
using System.Xml; 
using System.Xml.Serialization; 

[Serializable] 
public class Thing 
{ 
    [XmlAttribute] public string Name {get;set;} 
    public XmlNode Document { get; set; } 
} 

class Program 
{ 
    static void Main() 
    { 
    const string xml = @" 
<Thing Name=""George""> 
    <Document> 
    <subnode1/> 
    <subnode2/> 
    </Document> 
</Thing>"; 
    var s = new XmlSerializer(typeof(Thing)); 
    var thing = s.Deserialize(new StringReader(xml)) as Thing; 
    } 
} 

그러나, 문서 속성은 오히려 '문서'요소보다, 자식 요소 'subnode1'을 포함하고 있습니다.

XmlSerializer에서 Document를 'Document'요소가 포함 된 XmlNode로 설정할 수 있습니까?

(주의 : XmlElement [] 유형의 속성을 지정하고 [XmlAnyElement]로 표시하여 Document 요소를 가져올 수는 있지만, 'XmlAnyElement'라는 단일 요소가 아닌 인식 할 수없는 요소의 배열로 설정되어 있습니다. 문서 ')

+0

흠. 그게 수수께끼 야! DataContractSerializer도 동일한 동작을 나타냅니다. –

+0

구조는 항상 Document/subnode1, Document/subnode2입니까, 아니면 subnode3, subnode4 등입니까? 그렇다면 스키마를 Document/subnode (하위 노드 minOccurs = 0, maxOccurs = unbounded)로 수정 하시겠습니까? – code4life

+1

Document의 내용은 완전히 자유 형식이며, Deserializer가 Document의 첫 번째 자식 노드를 선택하는 방법을 보여주는 예제로만 존재합니다. – mackenir

답변

10

[XmlAnyElement] 특성으로 Document 속성을 표시해보십시오. 당신이 그들을 필터링해야합니다 그래서

[Serializable] 
public class Thing 
{ 
    [XmlAttribute] 
    public string Name {get;set;} 

    [XmlAnyElement] 
    public XmlNode Document { get; set; } 
} 

이, 당신은 (모든 공백이 우 ... 너무 직렬화 얻을) 단지 subnode1 및 subnode2 이상을 찾을 수 있다는 점에서 하나의 불행한 부작용이있을 것이다 :

class Program 
{ 
    static void Main() 
    { 
     const string xml = @" 
<Thing Name=""George""> 
    <Document> 
    <subnode1/> 
    <subnode2/> 
    </Document> 
</Thing>"; 
     var s = new XmlSerializer(typeof(Thing)); 
     var thing = s.Deserialize(new StringReader(xml)) as Thing; 

     foreach (XmlNode node in thing.Document) 
     { 
      // should filter to only subnode1 and subnode2. 
      if (node.Name != "" && node.Name != "#whitespace") 
      { 
       Console.WriteLine(node.Name); 
      } 
     } 

     Console.ReadLine(); 
    } 
} 

희망이 도움이됩니다.

+0

내 질문의 맨 아래에서 해결 방법은 XmlAnyElement 특성을 사용하는 것이지만 하나의 XmlNode에 배치 할 수 있다는 것을 알지 못했습니다. 그 텍스트를 추가하기 전에 당신이 대답했을 수도 있습니다. 나는 모든 인식 할 수없는 요소를 캡처하는 것을 선호한다. 그래서 나는 XML에서 오류를 발견 할 수있다. (즉, 하나의 자식 요소 만 있어야한다.) – mackenir

관련 문제