web-dev-qa-db-fra.com

XDocument obtient l'élément XML par la valeur de son attribut name

J'ai un résultat XML comme celui-ci

<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>

Je veux obtenir une liste d'objets, et chaque objet contiendra la valeur de ContaFirstname, ContaId, ContaJobTitle et ContaSurname

J'ai essayé quelque chose comme ça, mais ce n'est pas bien parce que je les ai tous NULL

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

Alors, comment accéder à ces éléments par leur nom?

18
kbaccouche

Vous ne voulez pas accéder aux éléments par nom car la plupart des gens interpréteraient cette déclaration. Vous souhaitez accéder aux éléments par la valeur de leur attribut name:

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

Vous voudrez peut-être résumer cela dans une méthode distincte, car cela va être difficile de le faire plusieurs fois. Par exemple:

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

Ensuite:

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

Si vous avez la possibilité de donner à votre document une structure plus sensée, ce serait préférable ...

32
Jon Skeet

Est-ce que cela résout votre problème:

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

ou, si vous voulez les valeurs (au lieu de 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