2012-10-30 2 views
1

다음과 같이 XML이 있습니다.Linq to XML 구문 분석

문자열 입력 ("IsAuthorFilterNeeded"또는 "IsTitleFilterNeeded")을 사용하고 해당 노드에서 책 코드 값을 반환하는 메서드를 작성해야합니다. 가정하자

매개 변수 "IsAuthorFilterNeeded"하면 내가이를 검색하는 Linq2XML 쿼리를 작성하는 노력 5,6,7,8

반환해야하지만 읽을 수 없습니다와 나는 코드 행복하지 않다 많은 하드 코드 된 문자열이 있습니다. 여기 내 linq2xml 쿼리입니다.

public IList<string> GetBookCodes(string filterOption) 
{ 
    IList<string> requiredValues = null; 

    foreach (var node in _xml.Descendants("BookOptions")) 
    { 
     if (node.Parent.Attribute("Name").Value == "ScienceBooks") 
     { 
      var requiredNode = node.Elements("Property").Attributes("Value").First(x => x.Parent.FirstAttribute.Value == filterOption); 
      requiredValues = requiredNode.Parent.Descendants("BookCode").Attributes("Value").ToArray().Select(x => x.Value).ToList(); 

      break; 
     } 
    } 
    return requiredValues; 
} 

더 간단한 코드로이 결과를 얻는 다른 방법이 있습니까?

<LibraryRack Id="3" Name="ScienceBooks"> 
     <Books> 
     <Book Id ="1" Name="Book1"></Book> 
     <Book Id ="2" Name="Book2"></Book > 
     <Book Id ="3" Name="Book3"></Book> 
     </Books> 
     <BookOptions> 
     <Property Name="IsAuthorFilterNeeded" Value ="1"> 
      <BookCode Value="5" /> 
      <BookCode Value="6" /> 
      <BookCode Value="7" /> 
      <BookCode Value="8" /> 
     </Property> 
     <Property Name="IsTitleFilterNeeded" Value ="0"> 
      <BookCode Value="2"/> 
      <BookCode Value="3"/> 
      <BookCode Value="4"/> 
      <BookCode Value="7"/> 
      <BookCode Value="129"/> 
     </Property> 
     </BookOptions> 

    </LibraryRack> 

답변

1

내가 유창하게 API를 여기

var propertyFilter = "IsAuthorFilterNeeded"; 
var query = xdoc.Descendants("LibraryRack") 
       .Where(lr => (string)lr.Attribute("Name") == "ScienceBooks") 
       .Descendants("Property") 
       .Where(p => (string)p.Attribute("Name") == propertyFilter) 
       .Descendants() 
       .Select(bc => (int)bc.Attribute("Value")); 
1

트릭을 할해야 LINQ의이 비트 (한 번 XML은 고정) :

public IList<string> GetBookCodes(string filterOption) 
{ 
    return (from property in _xml.Descendants("Property") 
      where (string)property.Attribute("Name") == filterOption 
      from value in property.Descendants("BookCode").Attributes("Value")     
      select (string)value).ToList(); 
} 
+2

그것은 것을 더 읽기 보인다 생각 두 번째'from' 절 앞에'where' 절 *을 두는 것이 더 효율적입니다. –

+0

@JonSkeet 좋은 캐치, 고마워. – HackedByChinese

+0

코드에서 "ScienceBooks"노드를 찾아야한다고 언급 한 부분이 있습니까? – Rockstart

1
using(FileStream fs = new FileStream("somedata.xml",FileMode.Open)) 
{ 
    var result = XDocument.Load(fs).Descendants("BookOptions"). 
            Descendants("Property"). 
            Where(c => { return c.Attribute("Name").Value.Trim() == "IsAuthorFilterNeeded"; }). 
            Descendants().Select(xe => xe.Attribute("Value")); 

    result.ToList().ForEach((val) => Console.WriteLine(val)); 
}