2016-08-31 30 views
2

I次の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"のものが1つしかないので、1つのAreaを取得することができますが、領域と同じ結果が得られます。私はxElement.Attribute( "name")というプログラムをどのように伝えるかわかりません。 "None"と比較したい値です。これはAccessLevelと比較したxElement.Attribute( "name")の値です。 。

私はすでにDescendants()を使用しようとしました。私はDescendants()を使ってみました。どこか(何か他のもの)ですが、私はコンパイルできません。

私は、私が使用したいエリアを得ることができます。

 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); 
     } 

、その後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ファイルが大きく、多数のユーザーがたくさんいるため、エリア。私はちょうど私の質問にXMLの一部を入れました。しかし、私がConfigDataをユーザーの代わりに使うと、私の問題は解決します。どうもありがとうございました! –

関連する問題