2009-09-25 8 views
1

Je veux trouver un élément simple (Nom) dans un fichier XML:C# Xpath requête pour trouver un seul nœud

<ZoneContentMapping> 
<ZoneContent> 
    <ContentId>72503</ContentId> 
    <StorefrontZoneId>Name</StorefrontZoneId> 
    <Type>ContentZone</Type> 
</ZoneContent> 
</ZoneContentMapping> 

que je fais:

XmlNodeList objNode = 
objXML.SelectNodes("ZoneContentMapping/ZoneContent[ContentId='72503']/StorefrontZoneId"); 

mon nombre de nœuds est toujours égale à zéro, Où vais-je mal?

+1

pouvez-vous afficher le code qui initialise objXML? – mjv

+0

Qu'est-ce que 'objXML' dans votre exemple de code? S'il vous plaît montrer son type, et aussi comment vous chargez l'exemple de XML ci-dessus. –

+0

I XmlDocument.LoadXml() 'd cet extrait, a exécuté le SelectNodes XPath et j'ai obtenu le seul nœud que vous cherchiez. Cela fait-il partie d'un document plus important ou quelque chose? – 48klocs

Répondre

3

Est-ce espaces de noms impliqués? J'ai eu un problème similaire à analyser les résultats Amazon AWS, qui s'est avéré être que je ne fournissais pas de XmlNamespaceManager avec l'espace de noms AWS spécifié.

XmlNamespaceManager mgr = new XmlNamespaceManager(m_xml.NameTable); 
mgr.AddNamespace("amzn", "http://s3.amazonaws.com/doc/2006-03-01/"); 

XmlNodeList nodes = xmlDoc.SelectNodes("//amzn:Contents", mgr); 

Le préfixe d'espace de noms est arbitraire, mais semble être nécessaire dans le XPath même si aucun préfixe d'espace de noms est utilisé dans le XML lui-même. Je ne pouvais pas trouver un moyen de lui dire d'associer un préfixe d'espace de noms vide à l'URL de l'espace de nommage spécifié.

0

Le XPath semble bien, tout comme le XML. Je l'ai essayé dans XmlSpy et j'ai "Nom" donc ça devrait marcher. Cependant, essayez d'ajouter une barre oblique supplémentaire au début juste au cas où ...

XmlNodeList objNode = objXML.SelectNodes ("/ZoneContentMapping/ZoneContent[ContentId='72503']/StorefrontZoneId"); 

Ou essayez SelectSingleNode à la place ...

-1

Voici une autre façon, vous pouvez aller à ce sujet si vous souhaitez:

 string XmlFilePath = @"C:\blablabla"; 

     XmlDocument LoadXmlDoc = new XmlDocument(); 
     LoadXmlDoc.Load(XmlFilePath); 

     XmlNodeList YourNodeList = LoadXmlDoc.GetElementsByTagName("StorefrontZoneId"); 

     LoadXmlDoc.Save(XmlFilePath); 
0

Je pense que le problème est ici le contexte dans lequel vous exécutez votre requête. Si vous chargez le document dans le moteur XPath que j'utilise ici, le contexte racine est le seul nœud fourni, ZoneContentMapping. Rappelez-vous que votre requête:

ZoneContentMapping/...

Développe à:

child::ZoneContentMapping/...

Comme l'axe par défaut dans XPath est child. Ainsi, votre requête recherche probablement un enfant de ZoneContentMapping appelé ZoneContentMapping. Oops.

Essayez:

self::ZoneContentMapping/ZoneContent[ContentId='72503']/StorefrontZoneId

Vous pouvez également préfixer un / à la requête, qui fait la recherche à partir de la racine du document XML, quel que soit votre contexte actuel.

+0

Dans des circonstances normales, le contexte par défaut est le _document node_ du document, qui deviendra root ('/') dans XPath, pas le nœud racine. –

0

Ce XPath fonctionne:

ZoneContentMapping/ZoneContent/StorefrontZoneId [preceding-sibling :: contentId = '72503']

et voici une bonne ressource:

http://www.codeguru.com/csharp/csharp/cs_misc/designtechniques/print.php/c7589__1/

+1

Et votre XPath est sémantiquement différent de son comment? Astuce: le XPath "non fonctionnel" dans la question ne suppose en aucun cas que "StorefrontZoneId était un enfant de ContentId". –

+0

C'est très différent! De plus, j'ai utilisé son xml et lui ai appliqué le xpath, et j'ai obtenu la valeur 'name' comme demandé. La seule chose que j'ai faite était d'utiliser XmlNode comme type au lieu de XmlNodeList – ScottE

Questions connexes