64 votes

Utilisation de Xpath avec un espace de noms par défaut en C #

J'ai un document XML avec un espace de noms par défaut. J'utilise un XPathNavigator pour sélectionner un ensemble de nœuds à l'aide de Xpath, comme suit:

 XmlElement myXML = ...;  
XPathNavigator navigator = myXML.CreateNavigator();
XPathNodeIterator result = navigator.Select("/outerelement/innerelement");
 

Je ne reçois aucun résultat: je suppose que c'est parce que je ne spécifie pas l'espace de noms. Comment puis-je inclure l'espace de noms dans ma sélection?

86voto

Marc Gravell Points 482669

D'abord, vous n'avez pas besoin d'un navigateur. SelectNodes / SelectSingleNode devrait suffire.

Vous pouvez toutefois avoir besoin d'un gestionnaire d'espaces de noms - par exemple:

 XmlElement el = ...; //TODO
XmlNamespaceManager nsmgr = new XmlNamespaceManager(
    el.OwnerDocument.NameTable);
nsmgr.AddNamespace("x", el.OwnerDocument.DocumentElement.NamespaceURI);
var nodes = el.SelectNodes(@"/x:outerelement/x:innerelement", nsmgr);
 

49voto

Cheeso Points 87022

Vous voudrez peut-être essayer un outil XPath Visualizer pour vous aider.

XPathVisualizer est gratuit, facile à utiliser.

texte alternatif

IMPORTANT: Si vous utilisez Windows 7/8 et ne voyez pas les éléments Fichier, Modifier et Menu Aide, veuillez appuyer sur la touche ALT.

29voto

user208185 Points 63

Pour ceux qui recherchent une solution de piratage rapide, en particulier dans les cas où vous connaissez le XML et n'avez pas à vous soucier des espaces de noms, vous pouvez contourner cette petite "fonctionnalité" ennuyeuse en lisant simplement le fichier en chaîne et remplacer l'attribut offensif:

 XmlDocument doc = new XmlDocument();
string fileData = File.ReadAllText(fileName);
fileData = fileData.Replace(" xmlns=\"", " whocares=\"");
using (StringReader sr = new StringReader(fileData))
{
   doc.Load(sr);
}

XmlNodeList nodeList = doc.SelectNodes("project/property");
 

Je trouve cela plus facile que tous les autres non-sens qui exigent un préfixe pour un espace de noms par défaut lorsque je traite avec un seul fichier. J'espère que cela t'aides.

20voto

Tomek Szpakowicz Points 5340

Lors de l'utilisation de XPath dans .NET (via un navigateur ou d'un SelectNodes/SelectSingleNode) sur XML avec des espaces de noms, vous devez:

  • fournir votre propre XmlNamespaceManager

  • et explicitement préfixe de tous les éléments d'une expression XPath, qui sont dans l'espace de noms.

Ce dernier est (reformulation de MME source lien ci-dessous): parce que XPath 1.0 ignore espace de noms par défaut (xmlns="some_namespace") spécifications. Ainsi, lorsque vous utilisez le nom de l'élément sans préfixe elle suppose null espace de noms.

C'est pourquoi .NET de la mise en œuvre de XPath ignore espace de noms avec le préfixe de la Chaîne.Vide dans XmlNamespaceManager et toujours utilise l'espace de noms null.

Voir XmlNamespaceManager et UndefinedXsltContext ne sais pas gérer l'espace de noms par défaut pour plus d'informations.

Je trouve cette "fonctionnalité" très gênant parce que vous ne pouvez pas faire de vieux XPath de l'espace de noms courant par le simple ajout d'espace de noms par défaut de déclaration, mais c'est la façon dont il fonctionne.

8voto

Vous pouvez utiliser l'instruction XPath sans utiliser XmlNamespaceManager comme ceci:

 ...
navigator.Select("//*[ local-name() = 'innerelement' and namespace-uri() = '' ]")
...
 

C'est un moyen simple de sélectionner un élément dans XML avec un espace de nom par défaut défini.

Le but est d'utiliser:

 namespace-uri() = ''
 

qui trouvera un élément avec un espace de noms par défaut sans utiliser de préfixes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X