2016-08-31 3 views
2

나는 다음과 같은 XML 파일이 있습니다XML을 Linq는 쿼리 (속성으로 요소를 얻을 수 및 속성 값)

<Object type="User"> 
    <Attribute name="Name">usernameExample</Attribute> 
    <Attribute name="Title">FHen</Attribute> 
    <Attribute name="AdministratedBy">Admin</Attribute> 
    <Attribute name="Password">123</Attribute> 
    <Attribute name="TimeOut">00:20:00</Attribute> 
    <Object type="AreasFolder"> 
     <Attribute name="Name">Areas</Attribute> 
     <Attribute name="Comment">This folder contains ...</Attribute> 
     <Object type="Area"> 
      <Attribute name="Name">RootArea</Attribute> 
      <Attribute name="AccessLevel">None</Attribute> 
     </Object> 
     <Object type="Area"> 
      <Attribute name="Name">FRF</Attribute> 
      <Attribute name="AccessLevel">Admin</Attribute> 
     </Object> 
    </Object> 
</Object> 

내 목표는 사용자 이름 = 없음 ACCESSLEVEL이없는 지역의 이름을 얻는 것입니다! . 이미 사용자 영역을 얻을 수 및 C# 논리를 사용하여 필터링 할 수 있지만 Linq XML 쿼리를 사용하여 할 싶습니다. 나는 이런 식으로 뭔가를하고 싶은,

public void tryXdoc(string username) 
    { 
     List<string> lista = new List<string>(); 

     XElement ConfigData = XElement.Load(UsersXmlPath); 

     XElement scadaUsers = 
      (from xElement in ConfigData.Elements("Object") 
       //where (string)xElement.Element("type") == "User" 
      select xElement).First(); 

     XElement usersFolder = 
      (from xElement in scadaUsers.Elements("Object") 
      where (string)xElement.Attribute("type") == "UsersFolder" 
      select xElement).First(); 

     IEnumerable<XElement> users = 
      from xElement in usersFolder.Elements("Object") 
      where (string)xElement.Attribute("type") == "User" 
      select xElement; 

     XElement user = 
      (from xElement in users 
       where (string)xElement.Element("Attribute").Attribute("name") == "Name" 
       && (string)xElement.Element("Attribute") == username 
       select xElement).First(); 

     XElement areasFolder = 
      (from xElement in user.Elements("Object") 
       where (string)xElement.Attribute("type") == "AreasFolder" 
       select xElement).First(); 

     IEnumerable<XElement> areas = 
      from xElement in areasFolder.Elements("Object") 
      where (string)xElement.Attribute("type") == "Area" 
      select xElement;   
    } 

을 이제 내 주에서

: 내 Logic.cs에서

logic.tryXdoc("usernameExample"); 

는 지금은 다음과 같은 짓을했는지 :

 IEnumerable<XElement> visibleAreas = 
      from xElement in areas.Elements("Attribute") 
      where 
      (string)xElement.Attribute("name") == "AccessLevel" 
      && (string)xElement.Attribute("name").Value != "None" 
      select xElement; 

AccessLevel! = "None"이 하나뿐이기 때문에 하나의 영역 만 가져 오지만 영역과 동일한 결과를 얻습니다. 내 프로그램에 xElement.Attribute ("name")을 알려주는 방법을 모르겠다. "None"과 비교할 값. AccessLevel과 비교 한 xElement.Attribute ("name")의 값. .

나는 이미 Descendants()를 사용하려고 시도했다. (어디에서) (그러나) 나는 같은 것을 얻는다. 나는 Descendants()를 사용하려고 시도했다. (something.Where (something else)) 그러나 나는 컴파일 할 수 없다. areaAttributes을 비교 한 후

 List<List<XElement>> listAreaAttributes = new List<List<XElement>>(); 

     foreach (XElement xElement in areas) 
     { 
      List<XElement> areaAttributes = new List<XElement>(); 

      foreach (XElement xEl in xElement.Elements("Attribute")) 
      { 
       areaAttributes.Add(xEl); 
      } 

      listAreaAttributes.Add(areaAttributes); 
     } 

및 그러나 나는 내가이 만드는 processment를 사용하지 않는 쿼리로 이것을 할 수 있습니다 알고

내가 사용하여 원하는 영역을 얻을 수 있습니다.

+0

이 문제에 대한 LINQ 쿼리를 작성할 수는 있습니다. 'visibleAreas'에서 기대할 수있는 값을 명확히 해 주시겠습니까? 전체''요소입니까? 아니면 단지 FRF'요소입니까? 또는 다른 것? – Ignas

+0

이 경우에는 FRF를 받고 싶습니다. 하지만 더 쉬울 경우 Area 객체 전체를 가져올 수 있습니다. 그런 다음 이름을 가져옵니다. 사용자의 경우 이름이 첫 번째 속성이지만 쿼리가 실제로 잘 수행되지 않았기 때문에 방금 작업했습니다 –

답변

1

사용자별로 적용하려는 경우 사용자에게 맞게 수정하는 것이 어떻습니까? 여기서는 XML의 순서가 정확하고 AccessLevel 이름이 항상 AccessLevel 바로 앞에있는 노드라고 가정합니다.

List<string> visibleAreas = ConfigData.Descendants("Attribute") 
    .Where(x => x.Attribute("name").Value == "AccessLevel") 
    .Where(x => x.Value != "None") 
    .Select(x => ((XElement)x.PreviousNode).Value) 
    .ToList(); 
+0

내 xml 파일이 크고 많은 사용자가 많기 때문에 해당 쿼리에 213 개의 결과가 표시됩니다 지역. 난 그냥 내 질문에 XML의 일부를 넣어. 하지만 사용자 대신 ConfigData를 사용하면 문제가 해결됩니다. 고마워요! –