Trouver un élément dans XDocument?

j'ai un XML simple

<AllBands>
  <Band>
    <Beatles ID="1234" started="1962">greatest Band<![CDATA[lalala]]></Beatles>
    <Last>1</Last>
    <Salary>2</Salary>
  </Band>
  <Band>
    <Doors ID="222" started="1968">regular Band<![CDATA[lalala]]></Doors>
    <Last>1</Last>
    <Salary>2</Salary>
  </Band>
</AllBands>

Cependant ,

quand je veux atteindre le "Doors band" et changer son ID:

  using (var stream = new StringReader(result))
            {
                XDocument xmlFile = XDocument.Load(stream);

                var query = from c in xmlFile.Elements("Band")

                            select c;
                             ...

query n'a pas de résultats

Mais

Si j'écris xmlFile.Elements().Elements("Band") donc il le trouve.

Quel est le problème ?

le chemin complet à partir de la racine est-il nécessaire ?

Et si oui , Pourquoi avait-il travailler sans spécifier <!--4 ?

le XDocument La Navigation me demande de connaître la structure complète du niveau jusqu'à l'élément requis ?

45
demandé sur Rune FS 2011-12-11 02:34:50

6 réponses

Elements() seulement les enfants directs - qui, dans le premier cas, c'est l'élément racine, dans le second cas, les enfants de l'élément racine, par conséquent, vous obtenez un match dans le deuxième cas. Si vous voulez juste un descendant correspondant, utilisez Descendants() au lieu de:

var query = from c in xmlFile.Descendants("Band") select c;

en outre, je vous suggérerais de restructurer votre Xml: le nom de bande devrait être un attribut ou une valeur d'élément, pas le nom d'élément lui - même- cela rend la interrogation (et la validation de schéma d'ailleurs) beaucoup plus difficile, c.-à-d. quelque chose comme ceci:

<Band>
  <BandProperties Name ="Doors" ID="222" started="1968" />
  <Description>regular Band<![CDATA[lalala]]></Description>
  <Last>1</Last>
  <Salary>2</Salary>
</Band>
68
répondu BrokenGlass 2011-12-10 22:39:13

Vous pouvez le faire de cette façon:

xml.Descendants().SingleOrDefault(p => p.Name.LocalName == "Name of the node to find")

où xml est un XDocument.

soyez conscient que le nom de la propriété renvoie un objet qui a un nom local et un espace de noms. C'est pour ça que tu dois utiliser un nom.LocalName si vous voulez comparer par nom.

24
répondu Francisco Goldenstein 2013-11-07 20:25:29

Vous devez utiliser Root pour se référer à l'élément racine:

xmlFile.Root.Elements("Band")

Si vous voulez trouver des éléments n'importe où dans le document, utilisez Descendants au lieu de:

xmlFile.Descendants("Band")
23
répondu Mark Byers 2011-12-10 22:38:36

Le problème est que Elements seulement direct éléments enfants de ce que vous appelez. Si vous voulez tous les descendants, utilisez le Descendants méthode:

var query = from c in xmlFile.Descendants("Band")
6
répondu Jon Skeet 2011-12-10 22:39:30

mon expérience lorsque je travaille avec des fichiers XML volumineux et compliqués est que parfois, ni les éléments ni les Descendants ne semblent fonctionner dans la récupération d'un élément spécifique (et je ne sais toujours pas pourquoi).

dans de tels cas, j'ai trouvé qu'une option beaucoup plus sûre est de rechercher manuellement l'élément, tel que décrit par le MSDN suivant post:

https://social.msdn.microsoft.com/Forums/vstudio/en-US/3d457c3b-292c-49e1-9fd4-9b6a950f9010/how-to-get-tag-name-of-xml-by-using-xdocument?forum=csharpgeneral

en bref, vous pouvez créer une fonction GetElement:

private XElement GetElement(XDocument doc,string elementName)
{
    foreach (XNode node in doc.DescendantNodes())
    {
        if (node is XElement)
        {
            XElement element = (XElement)node;
            if (element.Name.LocalName.Equals(elementName))
                return element;
        }
    }
    return null;
}

que vous pouvez alors appeler comme ceci:

XElement element = GetElement(doc,"Band");

notez que ceci reviendra null si aucun élément correspondant est trouvé.

3
répondu Human Wannabe 2017-12-05 10:51:29

Elements() la méthode retourne un IEnumerable<XElement> contenant tous les éléments enfants du nœud courant. Pour un XDocument, cette collection ne contient que l'élément racine. Par conséquent, ce qui suit est requis:

var query = from c in xmlFile.Root.Elements("Band")
            select c;
2
répondu Phil Klein 2011-12-10 22:41:01