Pregunta

Estoy probando un XPath muy básico este xml (igual que a continuación), y no encuentra nada.Estoy probando tanto .NET como este sitio web, y XPath como //PropertyGroup, /PropertyGroup y //MSBuildCommunityTasksPath simplemente no funcionan para mí (se compilaron pero no arrojaron resultados).

XML de origen:

<?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>
¿Fue útil?

Solución

Puede agregar espacios de nombres en su código y todo eso, pero efectivamente puede utilizar comodines en el espacio de nombres.Pruebe el siguiente modismo XPath.

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

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

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

EDITAR: Los espacios de nombres son geniales y no estoy sugiriendo que no sean importantes, pero utilizar comodines resulta útil cuando se combinan códigos prototipo, herramientas de escritorio únicas, se experimenta con XSLT, etc.Equilibre su necesidad de comodidad con el riesgo aceptable para la tarea en cuestión.Para su información, si es necesario, también puede eliminar o reasignar espacios de nombres.

Otros consejos

Las etiquetas del documento terminan en el espacio de nombres "predeterminado" creado por el atributo xmlns sin prefijo.Desafortunadamente, XPath por sí solo no puede consultar elementos en el espacio de nombres predeterminado.En realidad, no estoy seguro de los detalles semánticos, pero debes adjuntar explícitamente un prefijo a ese espacio de nombres usando cualquier herramienta que aloje 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 NameSpaceManager.Después de agregar explícitamente un espacio de nombres, puede realizar consultas utilizando el administrador de espacios de nombres como si todas las etiquetas en el elemento del 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);
        }
    }
}

Su problema es con el espacio de nombres (xmlns="http://schemas.microsoft.com/developer/msbuild/2003").Estás recibiendo cero nodos porque no lo estás 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 asignar un alias a un xmlns predeterminado con un identificador (ya que no se especifica ninguno en el atributo) y seleccionar como "//myXMLNStoken:PropertyGroup".

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top