Pregunta Problema XmlDocument.SelectSingleNode y xmlNamespace


Estoy cargando una cadena a un documento XML que contiene la siguiente estructura:

<?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>

entonces estoy cargando todo en xmldocument:

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

entonces ocurre el siguiente problema:

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

cuando elimino el atributo xmlns del elemento raíz (Proyecto) funciona bien, ¿Cómo puedo mejorar mi SelectSingleNode para devolver el elemento relevante?


34
2017-11-13 07:26


origen


Respuestas:


Deberías usar un XmlNamespaceManager en tu llamada a SelectSingleNode ():

XmlNamespaceManager ns = new XmlNamespaceManager(xmldoc.NameTable);
ns.AddNamespace("msbld", "http://schemas.microsoft.com/developer/msbuild/2003");
XmlNode node = xmldoc.SelectSingleNode("//msbld:Compile", ns);

70
2017-11-13 07:32



Tomado desde el documentación de SelectSingleNode() en el MSDN:

Nota
  Si la expresión XPath no incluye un prefijo, se supone que   URI del espacio de nombres es el espacio de nombres vacío. Si su XML incluye un valor predeterminado   espacio de nombres, aún debe agregar un prefijo y URI de espacio de nombres al   XmlNamespaceManager; de lo contrario, no obtendrá un nodo seleccionado. por   más información, ver Seleccionar nodos con XPath Navigation.

Y el siguiente código de muestra es

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

Sus  no  como  Si  esta  haría  ser "oculto  conocimiento". ;-)


17
2017-11-13 07:32



Dado que 'ItemGroup' puede tener múltiples hijos 'Compile', y usted específicamente desea los hijos 'Compile' de 'Project / ItemGroup', lo siguiente devolverá todos los hijos 'Compilar' deseados y no otros:

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);

Tenga en cuenta que la especificación del espacio de nombres 'msbld:' debe preceder a cada nivel de nodo.


2
2018-06-14 15:37



De esta manera no es necesario especificar el espacio de nombres:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("your xml");
XmlNode node = xmlDoc.SelectSingleNode("/*[local-name() = 'Compile']");
XmlNode nodeToImport = xmlDoc2.ImportNode(node, true);
xmlDoc2.AppendChild(nodeToImport);

0
2018-02-14 10:15