XmlDocument.SelectSingleNode et xmlnamespace

je charge une chaîne de caractères dans un document XML qui contient la structure suivante:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">                  
  <ItemGroup>
    <Compile Include="clsWorker.cs" />        
  </ItemGroup>      
</Project>

puis im loading all dans xmldocument:

XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(Xml);

puis le problème suivant se produit:

XmlNode Node = xmldoc.SelectSingleNode("//Compile"); // return null

quand je supprime l'attribut xmlns de l'élément racine (projet) son fonctionnement amende, Comment puis-je améliorer ma SelectSingleNode pour retourner l'élément concerné ?

34
demandé sur Shlomi Komemi 2010-11-13 10:26:07

4 réponses

vous devez utiliser un XmlNamespaceManager dans votre appel à SelectSingleNode () :

XmlNamespaceManager ns = new XmlNamespaceManager(xmldoc.NameTable);
ns.AddNamespace("msbld", "http://schemas.microsoft.com/developer/msbuild/2003");
XmlNode node = xmldoc.SelectSingleNode("//msbld:Compile", ns);
72
répondu Frédéric Hamidi 2011-07-18 20:21:41

tiré à droite de la documentation de SelectSingleNode() sur le MSDN :

Note

Si L'expression XPath ne comporte pas de préfixe, il est supposé que le L'URI d'espace de noms est l'espace de noms vide. si votre XML inclut une valeur par défaut namespace, vous devez quand même ajouter un préfixe et un URI namespace XmlNamespaceManager; autrement, vous n'obtiendrez pas de noeud sélectionné. pour pour plus d'informations, voir sélectionnez les noeuds en utilisant la Navigation XPath .

et le code d'échantillon qui suit immédiatement est

XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("ab", "http://www.lucernepublishing.com");
XmlNode book = doc.SelectSingleNode("//ab:book", nsmgr);

Il est pas comme si ce serait être " caché connaissances ". ;- )

17
répondu Tomalak 2017-05-23 12:17:39

puisque le 'groupe D'items' peut avoir plusieurs enfants 'compiler', et que vous voulez spécifiquement les enfants' compiler ' du 'groupe de projet / Item' , les suivants retourneront tous les enfants 'compiler' désirés et aucun autre:

XmlDocument projectDoc = new XmlDocument();
projectDoc.Load(projectDocPath);
XmlNamespaceManager ns = new XmlNamespaceManager(projectDoc.NameTable);
ns.AddNamespace("msbld", "http://schemas.microsoft.com/developer/msbuild/2003");
XmlNodeList xnList = projectDoc.SelectNodes(@"/msbld:Project/msbld:ItemGroup/msbld:Compile", ns);

noter que la spécification 'msbld:' namespace doit précéder chaque niveau de noeud.

2
répondu user3902302 2016-06-14 15:37:36

de cette façon, vous n'avez pas besoin de spécifier l'espace de noms:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("your xml");
XmlNode node = xmlDoc.SelectSingleNode("/*[local-name() = 'Compile']");
XmlNode nodeToImport = xmlDoc2.ImportNode(node, true);
xmlDoc2.AppendChild(nodeToImport);
1
répondu Bruno B 2018-02-14 10:15:49