2011-01-13 6 views
1

안녕하세요, 제가 읽은 튜토리얼에서 간단한 linq 쿼리를 작성하려고합니다. 하지만 나는 그것이 작동하도록 할 수 없습니다. 첨부 된 XML 문서에 주소를 모두 표시하려고하지만 첫 번째 문서 만 표시 할 수 있습니다. 다른 사람이 왜 둘 다 인쇄되지 않는지 알아낼 수 있습니까? 대단히 감사합니다.linq to xml to descendants

<?xml version="1.0" encoding="utf-8" ?> 
<Emails> 
    <Email group="FooBar"> 
    <Subject>Test subject</Subject> 
    <Content>Test Content</Content> 
    <EmailTo> 
     <Address>[email protected]</Address> 
     <Address>[email protected]</Address> 
    </EmailTo> 
    </Email> 
</Emails> 




    Dim steve = (From email In emailList.Descendants("Email") _ 
       Where (email.Attribute("group").Value.Equals("FooBar")) _ 
       Select content = email.Element("EmailTo").Descendants("Address")).ToList() 



    If Not steve Is Nothing Then 
     For Each addr In steve 
      Console.WriteLine(addr.Value) 
     Next 
     Console.ReadLine() 
    End If 

답변

2

현재 쿼리는 List<IEnumerable<XElement>>을 반환합니다. 즉, 두 개의 중첩 된 foreach 루프가 필요합니다. 하나는 목록을 반복하고 다른 하나는 IEnumerable<XElement>의 내용을 반복합니다.

대신 Enumerable.SelectMany 메서드를 사용하도록 LINQ 쿼리를 업데이트하고 주소를 직접 가져올 수 있습니다. 쿼리 형식에서 SelectMany은 두 번째 from 절을 사용하여 하위 쿼리를 나타냅니다. 이것은 다음과 유사합니다 :

또한
Dim query = (From email In emailList.Descendants("Email") _ 
      Where (email.Attribute("group").Value.Equals("FooBar")) _ 
      From addr In email.Element("EmailTo").Descendants("Address") _ 
      Select addr.Value).ToList() 

If query.Any() Then 
    For Each addr In query 
     Console.WriteLine(addr) 
    Next 
End If 

ToList이 필요하지 않은 경우에만 결과를 반복 할 기타 다른 목적 목록으로 결과를 사용하지 않는 경우.

편집 : 첫 번째

:이 쿼리 작품의 2 개 부분으로 그것을 파괴 할 방법을 설명하는 모든 <Email> 노드

From email In emailList.Descendants("Email") _ 
Where (email.Attribute("group").Value.Equals("FooBar")) _ 

이 쿼리와 만 을 가지고있는 사람과 일치 그룹 "FooBar"의 속성 값.

둘째 :

From addr In email.Element("EmailTo").Descendants("Address") _ 
Select addr.Value 

이것은 첫 번째 부분 (위) 종료 위치를 계속 부질이다. 이는 원래 쿼리의 결과를 더 자세히 쿼리하는 방법입니다. 여기서 우리는 모든 <Address> 노드를 쿼리하고 마지막으로 노드의 내부 텍스트에 대해 Value을 선택합니다. 이 작업을 수행해야하는 이유는 Descendants("Address")이 모든 "주소"요소를 포함하는 IEnumerable<XElement>을 반환하기 때문입니다. 이러한 값을 반복하고 값을 추출하려면 추가 쿼리 (또는 foreach)를 수행해야합니다.

이를 설명하는 또 다른 방법은이 쿼리를 분해하는 것입니다 :

Dim query1 = From email In emailList.Descendants("Email") _ 
      Where (email.Attribute("group").Value.Equals("FooBar")) 
      Select email.Element("EmailTo").Descendants("Address") 
Dim query2 = query1.SelectMany(Function(addr) addr.Select(Function(a) a.Value)) 

공지 사항 query2에서 SelectMany의 사용. 에있는 Select은 앞에서 언급 한 IEnumerable을 반복하는 추가 작업입니다. 원래 쿼리는 query1/query2보다 명확하지만, 그 점을 명확히하기 위해 쓴 것입니다.

+0

linq 문이 어떻게 작동하는지 완전히 이해하지 못합니다. 당신은 나를 위해 그것을 무너 뜨릴 수 있거나 내가 읽을 수있는 자원을 가르쳐 주시겠습니까? 내가 이해하지 못하는 것은 두 번째 from 절입니다. 그게 내가 필요한 것을 어떻게 내줄 까? 대답을 주셔서 감사합니다 도움 – gh9

+0

죄송합니다, 단지 리턴 결과를 보면서 내가 기대하고있는 결과가 [email protected] NEWLINE [email protected] 내가 무엇입니까 것은 [email protected] NEWLINE [email protected] – gh9

+0

아, 내 실수에는 선택 진술이 포함되지 않았다. 답변은 광고 된대로 작동합니다. 왜 작동하는지 설명 할 수 있습니까?고맙습니다. – gh9