2012-12-14 2 views
2

내가 XML을 구문 분석을 시도하고는 다음과 같다 :구문 분석 XML

<Item status="SUCCESS" message=""> 
    <ItemDate>12/21/2012 
     <ItemType>MyType1 
     <ItemUrl title="ItemTitle">http://www.itemurl1.com</ItemUrl> 
     </ItemType> 
    </ItemDate> 
    <ItemDate>12/22/2012 
     <ItemType>MyType2 
     <ItemUrl title="Item2Title">http://www.itemurl2.com</ItemUrl> 
     </ItemType> 
    </ItemDate> 
</Item> 

당신은 우리가이 XML을 호출 할 수 있는지 확실하지 않습니다 볼 수 있지만, 내가 밖으로 무엇을 얻을 SI로 레거시 서비스. 내가 한 것은 이것을 파싱하여 객체 그래프에로드하는 것입니다. 내 객체 모델은 다음과 같습니다 :

public class Item 
    { 
     public string Date { get; set; } 
     public string Type { get; set; } 
     public string Url { get; set; } 
     public string Title { get; set; } 
    } 

그래서 위의 xml/string을 구문 분석하면 기본적으로 Item 객체 컬렉션이 생성됩니다. 일부 코드 스 니펫으로이를 달성하는 방법을 제안 해 주시겠습니까?

나는 XDocument를 사용해 보았지만 xml의 특이한 구조로는 할 수 없었다.

감사합니다, lazyberezovsky'sLinq2Xml 투사하는 대신 - 마이크

+0

속성 이름 앞에 클래스 이름을 접두사로 사용하면 안됩니다. 중복됩니다. –

답변

2
XDocument xdoc = XDocument.Load(path_to_xml); 
var query = from date in xdoc.Descendants("ItemDate") 
      let type = date.Element("ItemType") 
      let url = type.Element("ItemUrl") 
      select new Item() 
      { 
       ItemDate = ((XText)date.FirstNode).Value, 
       ItemType = ((XText)type.FirstNode).Value, 
       ItemUrl = (string)url, 
       ItemTitle = (string)url.Attribute("title"), 
      }; 
+0

나는 위를 실행할 때 아이템이 하나 밖에없고 컬렉션이 아니라는 것을 알았습니다. 저는 var doc = XDocument.Parse (documents)를 사용합니다. 여기서 documents는 xml 문자열입니다. – Mike

+0

@Mike 당신은 간단하게'ToList();'를'query' 객체에 추가하여 콜렉션을 얻을 수 있습니다. – chridam

+0

그래도 한 항목 만 남았습니다. – Mike

1

은 또한 XML을로드하기 전에 Xml Transform를 사용하여 평평하고 고려할 수 있습니다.

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       version="1.0" 
       > 
    <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" indent="yes" /> 

    <xsl:template match="/"> 
     <Items> 
      <xsl:apply-templates select="Item/ItemDate" /> 
     </Items> 
    </xsl:template> 

    <xsl:template match="ItemDate"> 
     <Item> 
      <xsl:attribute name="ItemDate"> 
       <xsl:value-of select="normalize-space(./text()[1])" /> 
      </xsl:attribute> 
      <xsl:attribute name="ItemType"> 
       <xsl:value-of select="normalize-space(ItemType/text()[1])" /> 
      </xsl:attribute> 
      <xsl:attribute name="ItemUrl"> 
       <xsl:value-of select="normalize-space(ItemType/ItemUrl/text()[1])" /> 
      </xsl:attribute> 
      <xsl:attribute name="ItemTitle"> 
       <xsl:value-of select="normalize-space(ItemType/ItemUrl/@title)" /> 
      </xsl:attribute> 
     </Item> 
    </xsl:template> 
</xsl:stylesheet> 

이렇게하면 다음과 같은 XML이 생성됩니다.이 XML은 deserialize하기 쉽습니다. [XmlAttribute]attribute을 XmlDocument와 함께 사용하십시오.

<Items> 
    <Item ItemDate="12/21/2012" ItemType="MyType1" ItemUrl="http://www.itemurl1.com" ItemTitle="ItemTitle" /> 
    <Item ItemDate="12/22/2012" ItemType="MyType2" ItemUrl="http://www.itemurl2.com" ItemTitle="Item2Title" /> 
</Items> 
1

전송 된 XML에 노드 항목이 한 번만 있으므로 lazyberezovsky 코드에서 하나의 항목 만 가져옵니다. 그리고 그것은 맞습니다. 항목을 가져오고 ItemDate 노드로로드하려고한다고 가정합니다. 이렇게하려면 다음 수정 된 코드를 사용하십시오.

XDocument xdoc = XDocument.Load(new StringReader(xml)); 
var query = from i in xdoc.Descendants("ItemDate") 
        let date = i 
        let type = date.Element("ItemType") 
        let url = type.Element("ItemUrl") 
        select new Item() 
          { 
           Date = ((XText) date.FirstNode).Value, 
           Type = ((XText) type.FirstNode).Value, 
           Url = (string) url, 
           Title = (string) url.Attribute("title"), 
          }; 
     var items = query.ToList();