web-dev-qa-db-ja.com

XDocumentを使用して属性で要素を検索

このクエリは有効なようですが、結果は0です。

IEnumerable<XElement> users =
            (from el in XMLDoc.Elements("Users")
             where (string)el.Attribute("GUID") == userGUID.ToString()
             select el);

私のXMLは次のとおりです。

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Users>
  <User GUID="68327fe2-d6f0-403b-a7b6-51860fbf0b2f">
    <Key ID="F7000012ECEAD101">
      ...
    </Key>
  </User>

</Users>

これに光を当てる手がかりはありますか?

24
Nacho

2行目のUsersUserに変更します。このような:

    IEnumerable<XElement> users = (from el in XMLDoc.Root.Elements("User")
                                   where (string)el.Attribute("GUID") ==  userGUID.ToString()
                                   select el);

XMLDocはXDocumentであり、ルート要素自体ではないと仮定しています。

32
Patrick Karcher

さて、sers要素にはGUID属性がありません。2つの推奨オプションがあります:

  • XDocument.Root.Elements("User")を見てください
  • Descendants("User")を使用して、allユーザー要素を見つけます。

とりあえず前者に固執します。それは私たちに与えます:

IEnumerable<XElement> users =
            (from el in XMLDoc.Root.Elements("User")
             where (string) el.Attribute("GUID") == userGUID.ToString()
             select el);

さて、これをさらに整理することができます。まず、Guidの代わりにstringにキャストしましょう。

IEnumerable<XElement> users =
    (from el in XMLDoc.Root.Elements("User")
     where (Guid) el.Attribute("GUID") == userGUID
     select el);

ただし、ここでクエリ式を使用する理由はあまりありません...適用するのは単一の述語だけです。 Whereメソッドを直接使用してみましょう:

IEnumerable<XElement> users = 
    XMLDoc.Root
          .Elements("User")
          .Where(el => (Guid) el.Attribute("GUID") == userGUID);

もちろん、それをどのようにレイアウトするかはあなた次第です:)長い行では、おそらくすべてを長い最初の行の下に揃えることができます:

IEnumerable<XElement> users = XMLDoc.Root
                                    . etc

さて、最後に-User要素にGUID属性がない場合はどうでしょうか?現在、このコードは例外をスローします。そうではありません。代わりにNullable<Guid> aka Guid?にキャストすることで、そのようなことを無視させることができます。

IEnumerable<XElement> users = 
    XMLDoc.Root
          .Elements("User")
          .Where(el => (Guid?) el.Attribute("GUID") == userGUID);
47
Jon Skeet