Pergunta

Eu estou tentando um XPath muito básico em este xml (o mesmo que abaixo), e isso não acontece encontrar nada. Eu estou tentando tanto .NET e este site, e XPaths como //PropertyGroup, /PropertyGroup e //MSBuildCommunityTasksPath são simplesmente não funciona para mim (que compilou mas retornam resultados zero).

XML Fonte:

<?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>
Foi útil?

Solução

Você pode adicionar namespaces em seu código e tudo isso, mas você pode efetivamente curinga do namespace. Tente o seguinte XPath idioma.

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

name () geralmente funciona bem, como em:

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

EDIT: Namespaces são grandes e eu não estou sugerindo que eles não são importantes, mas wildcarding deles vem a calhar quando cobbling código do protótipo juntos, one-off ferramentas de desktop, experimentando com XSLT, e assim por diante. Equilibrar a sua necessidade de conveniência contra o risco aceitável para a tarefa em mãos. FYI, se for necessário, você também pode tirar ou namespaces Reatribuir.

Outras dicas

As tags no documento acabar no namespace "default" criado pelo atributo xmlns sem prefixo. Infelizmente, XPath sozinho não pode consultar elementos no namespace padrão. Estou realmente não tenho certeza dos detalhes semânticos, mas você tem que anexar explicitamente um prefixo para que namespace utilizando XPath qualquer ferramenta está hospedando.

Pode haver um caminho mais curto para fazer isso no .NET, mas a única maneira que eu vi é através de um NamespaceManager. Depois de adicionar explicitamente um namespace, você pode consultar usando o gerenciador de namespace como se todas as tags no elemento namespaced ter esse prefixo (eu escolhi '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);
        }
    }
}

Seu problema é com o namespace (xmlns = "http://schemas.microsoft.com/developer/msbuild/2003"). Você está recebendo zero de nós porque você não está qualificando-o com o namespace. Se você remover o atributo xmlns, o seu "// PropertyGroup" XPath vai funcionar. Como você consulta com namespace normalmente envolve aliasing um xmlns padrão para um identificador (uma vez que não é especificado no atributo), e selecionando como. "// myXMLNStoken: PropertyGroup"

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top