test namespace examples ejemplo checker xml xpath namespaces

namespace - xpath xml



¿Qué pasa con mi XPath/XML? (4)

Estoy intentando un XPath muy básico en este xml (lo mismo que a continuación), y no encuentra nada. Estoy probando .NET y este sitio web , y XPaths como //PropertyGroup , /PropertyGroup y //MSBuildCommunityTasksPath simplemente no funcionan para mí (se compilan pero devuelven cero resultados).

Fuente XML:

<?xml version="1.0" encoding="utf-8"?> <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <!-- $Id: FxCop.proj 114 2006-03-14 06:32:46Z pwelter34 $ --> <PropertyGroup> <MSBuildCommunityTasksPath>$(MSBuildProjectDirectory)/MSBuild.Community.Tasks/bin/Debug</MSBuildCommunityTasksPath> </PropertyGroup> <Import Project="$(MSBuildProjectDirectory)/MSBuild.Community.Tasks/MSBuild.Community.Tasks.Targets" /> <Target Name="DoFxCop"> <FxCop TargetAssemblies="$(MSBuildCommunityTasksPath)/MSBuild.Community.Tasks.dll" RuleLibraries="@(FxCopRuleAssemblies)" AnalysisReportFileName="Test.html" DependencyDirectories="$(MSBuildCommunityTasksPath)" FailOnError="True" ApplyOutXsl="True" OutputXslFileName="C:/Program Files/Microsoft FxCop 1.32/Xml/FxCopReport.xsl" /> </Target> </Project>


Las etiquetas en el documento terminan en el espacio de nombres "predeterminado" creado por el atributo xmlns sin prefijo. Desafortunadamente, XPath solo no puede consultar elementos en el espacio de nombres predeterminado. En realidad, no estoy seguro de los detalles semánticos, pero tienes que adjuntar explícitamente un prefijo a ese espacio de nombres usando la herramienta que hospeda XPath.

Puede haber una forma más corta de hacer esto en .NET, pero la única forma que he visto es a través de un NameSpaceManager. Después de que agregue explícitamente un espacio de nombres, puede consultar utilizando el administrador de espacio de nombres como si todas las etiquetas en el elemento de espacio de nombres tuvieran ese prefijo (elegí ''msbuild''):

using System; using System.Xml; public class XPathNamespace { public static void Main(string[] args) { XmlDocument xmlDocument = new XmlDocument(); xmlDocument.LoadXml( @"<?xml version=""1.0"" encoding=""utf-8""?> <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003""> <!-- $Id: FxCop.proj 114 2006-03-14 06:32:46Z pwelter34 $ --> <PropertyGroup> <MSBuildCommunityTasksPath>$(MSBuildProjectDirectory)/MSBuild.Community.Tasks/bin/Debug</MSBuildCommunityTasksPath> </PropertyGroup> <Import Project=""$(MSBuildProjectDirectory)/MSBuild.Community.Tasks/MSBuild.Community.Tasks.Targets""/> <Target Name=""DoFxCop""> <FxCop TargetAssemblies=""$(MSBuildCommunityTasksPath)/MSBuild.Community.Tasks.dll"" RuleLibraries=""@(FxCopRuleAssemblies)"" AnalysisReportFileName=""Test.html"" DependencyDirectories=""$(MSBuildCommunityTasksPath)"" FailOnError=""True"" ApplyOutXsl=""True"" OutputXslFileName=""C:/Program Files/Microsoft FxCop 1.32/Xml/FxCopReport.xsl"" /> </Target> </Project>"); XmlNamespaceManager namespaceManager = new XmlNamespaceManager(xmlDocument.NameTable); namespaceManager.AddNamespace("msbuild", "http://schemas.microsoft.com/developer/msbuild/2003"); foreach (XmlNode n in xmlDocument.SelectNodes("//msbuild:MSBuildCommunityTasksPath", namespaceManager)) { Console.WriteLine(n.InnerText); } } }


Por favor, muéstranos el código que estás utilizando, ya que sospecho que tiene más que ver con la forma en que interpretas los resultados ... En tu ejemplo, PropertyGroup debería devolver una lista con un solo objeto y si ejecutas un "get text" "método en él, debe devolver el contenido de MSBuildCommunityTasksPath ya que ese es el único subelemento.


Su problema es con el espacio de nombres (xmlns = "http://schemas.microsoft.com/developer/msbuild/2003"). Está recibiendo cero nodos porque no lo está calificando con el espacio de nombres. Si elimina el atributo xmlns, su XPath "// PropertyGroup" funcionará. La forma de consultar con el espacio de nombres generalmente implica aliasing un xmlns predeterminado a un identificador (ya que uno no se especifica en el atributo) y seleccionando "// myXMLNStoken: PropertyGroup".


Puede agregar espacios de nombres en su código y todo eso, pero puede comodín efectivamente el espacio de nombres. Pruebe la siguiente frase idiomática de XPath.

//*[local-name()=''PropertyGroup''] //*[local-name()=''MSBuildCommunityTasksPath'']

name () generalmente también funciona, como en:

//*[name()=''PropertyGroup''] //*[name()=''MSBuildCommunityTasksPath'']

EDITAR: Los espacios de nombres son geniales y no estoy sugiriendo que no sean importantes, pero los comodines son útiles cuando se combinan códigos de prototipos, herramientas de escritorio únicas, experimentos con XSLT, etc. Equilibre su necesidad de conveniencia contra el riesgo aceptable para la tarea en cuestión. Para su información, si es necesario, también puede quitar o reasignar espacios de nombres.