2010-01-18 5 views
3

LINQ to XML을 사용하여 XML 파일의 정보를 개체로 추출하려고합니다. 문서 및 섹션 ID 특성을 반환 할 수는 있지만 각 섹션 요소의 항목에 액세스 할 수는 없지만 문서의 모든 항목에 대해 IEnumerable을 반환합니다. 나는 이것이 Descendants를 호출 할 때 정확하다는 것을 알고 있지만 각 섹션 요소의 자식 항목 만 반환하도록 고심하고 있습니다. 아무도 도와 줄 수 있니?LINQ to XML 하위 요소 선택

XML 문서

<root> 
<document id="1"> 
    <section id="1.1"> 
    <item id="1.1.1"></item> 
    <item id="1.1.2"></item> 
    <item id="1.1.3"></item> 
    </section> 
    <section id="1.2"> 
    <item id="1.2.1"></item> 
    <item id="1.2.2"></item> 
    </section> 
</document> 
</root> 

LINQ 쿼리

XElement documentRoot = XElement.Load("document.xml"); 
var documents = (from docs in documentRoot.Descendants("document") 
       select new 
        { 
         Id = (string) docs.Attribute("id"), 
         Sections = docs.Elements("section"), 
         Items = docs.Elements("section").Elements("item") 
        }).ToList(); 

foreach(var doc in documents) 
{ 
    foreach(var section in doc.Sections) 
    { 
     Console.WriteLine("SectionId: " + section.Attribute("Id")); 
     foreach(var item in doc.Items) 
     { 
      Console.WriteLine("ItemId: " + section.Attribute("Id")); 
     } 
    } 
} 
+1

나는 약간의 목적이 명확하지 않다. 익명 객체는 문서 ID, 문서의 모든 섹션 및 문서의 모든 섹션에있는 모든 항목으로 구성됩니다. XML 계층 구조를 익명 객체로 재구성하려는 경우 여러 쿼리가 필요할 것입니다. 왜 그런 경우 XML을 사용하지 않는 것이 좋을까요? – womp

답변

6

당신은 속성 Id과 항목 루프에서, 몇 가지 작은 오타를 얻었다. 하지만 모든 항목을 해당 항목 컬렉션으로 가져 오려고하는 경우 ItemsDocument이 아닌 Section 속성이어야하므로 디자인 수준에서 잘못되었습니다 (따라서 XML을 두 번 쿼리해야합니다). 당신이 할 수있는

하거나, 뭔가를 할 수 있습니다 :

var documents = 
    (from docs in documentRoot.Descendants("document") 
    select new 
    { 
     Id = (string) docs.Attribute("id"), 
     Sections = docs.Elements("section") 
    }).ToList(); 

foreach (var doc in documents) 
{ 
    foreach (var section in doc.Sections) 
    { 
     Console.WriteLine("SectionId: " + section.Attribute("id")); 
     foreach (var item in section.Elements("item")) 
     { 
      Console.WriteLine("ItemId: " + item.Attribute("id")); 
     } 
    } 
} 

출력 :

 
SectionId: id="1.1" 
ItemId: id="1.1.1" 
ItemId: id="1.1.2" 
ItemId: id="1.1.3" 
SectionId: id="1.2" 
ItemId: id="1.2.1" 
ItemId: id="1.2.2" 
+0

오타로 인해 미안하지만 여전히 문제를 해결하지 못합니다. 내가 습득하려고하는 것은 각 섹션에 대한 하위 항목 만 반환된다는 것입니다. – Cragly

+0

@Cragly, 방금 내 대답을 다시 작성했습니다.보세요 –

+0

우수! 매력처럼 작동합니다. 그런 간단한 수정. 이 나무를 너무 오랫동안 보면서 나무를 보지 못했을 것입니다. 좋은 사람. – Cragly

2

당신이 평면 구조를 원하십니까?!?!

XElement documentRoot = XElement.Parse (
@"<root> 
<document id='1'> 
    <section id='1.1'> 
    <item id='1.1.1'></item> 
    <item id='1.1.2'></item> 
    <item id='1.1.3'></item> 
    </section> 
    <section id='1.2'> 
    <item id='1.2.1'></item> 
    <item id='1.2.2'></item> 
    </section> 
</document> 
</root> 
"); 




var documents = (from docs in documentRoot.Descendants("section") 
       select new 
        { 
         SectionId = (string) docs.Attribute("id"), 
         Items = docs.Elements("item") 
        }); 
documents.Dump(); 

(LinqPad부터)이 관련된 항목들 XElement는 containes 2 개 SectionId 아이템을 제공한다.

+0

게시물 주셔서 고마워요하지만 내가 idealy 것이 좋아하는 항목 XElements에 액세스 할 수 있고 개체의 항목 속성에 할당 할 수 있도록 IEnumerable 해당 특정 섹션과 관련된. – Cragly

+0

갖고 싶은 데이터 구조의 예를 들려 줄 수 있습니까? 유형 대신 XElement를 사용해야하는 이유는 무엇입니까?!?! – salgo60