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 ?
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>
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.
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")
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")
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:
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é.
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;