web-dev-qa-db-ja.com

XDocumentは、name属性の値によってXML要素を取得します

このようなXML結果があります

<response>
  <lst name="responseHeader">
    <int name="status">0</int>
    <int name="QTime">16</int>
  </lst>
  <result name="response" numFound="3" start="0" maxScore="1.0">
    <doc>
      <str name="ContaFirstname">
        firstname1                                                   
      </str>
      <str name="ContaId">6557</str>
      <str name="ContaJobTitle">Manager</str>
      <str name="ContaSurname">surname1
      </str>
    </doc>
    <doc>
      <str name="ContaFirstname">firstname2</str>
      <str name="ContaId">6203</str>
      <str name="ContaJobTitle">Director</str>
      <str name="ContaSurname">surname2</str>
    </doc>
  </result>
</response>

オブジェクトのリストを取得したいのですが、すべてのオブジェクトにContaFirstnameContaIdContaJobTitleおよびContaSurnameの値が含まれます。

私はこのようなものを試しましたが、それはすべてがNULLになるので正しくありません

var test = from c in xml.Descendants("doc")
                    select new 
                    {
                        firstname = c.Element("ContaFirstname"),
                        surnmane = c.Element("ContaSurname")
                    }; 

では、これらの要素に名前でどのようにアクセスできますか?

18
kbaccouche

ほとんどの人がその文を解釈するため、nameで要素にアクセスしたくありません。 name属性の値によって要素にアクセスしたい場合:

firstname = (string) c.Elements("str")
                      .First(x => x.Attribute("name").Value == "ContaFirstname");
//etc

それを別のメソッドに抽象化したいと思うかもしれません。それを複数回行うのは苦痛になるからです。例えば:

public static XElement ElementByNameAttribute(this XContainer container,
                                              string name)
{
    return container.Elements("str")
                    .First(x => x.Attribute("name").Value == name);
}

次に:

var test = from c in xml.Descendants("doc")
           select new 
           { 
               firstname = c.ElementByNameAttribute("ContaFirstname").Value,
               surnmane = c.ElementByNameAttribute("ContaSurname").Value
           }; 

文書にもっと理にかなった構造を与える機会があれば、それが望ましいでしょう...

32
Jon Skeet

これはあなたの問題を解決しますか:

var test = from c in xml.Descendants("doc")
           select new 
           {
               firstname = c.Elements("str").First(element => element.Attribute("name").Value == "ContaFirstname"),
               surnmane = c.Elements("str").First(element => element.Attribute("name").Value == "ContaSurname")
           }; 

または、値が必要な場合(XElementの代わりに:

var test = from c in xml.Descendants("doc")
           select new 
           {
               firstname = c.Elements("str").First(element => element.Attribute("name").Value == "ContaFirstname").Value,
               surnmane = c.Elements("str").First(element => element.Attribute("name").Value == "ContaSurname").Value
           }; 
3
Cédric Bignon