10

我正在这个 xml上尝试一个非常基本的 XPath (如下所示),但它没有找到任何东西。我正在尝试 .NET 和这个网站,以及 XPaths,例如//PropertyGroup/PropertyGroup并且//MSBuildCommunityTasksPath根本不适合我(他们编译但返回零结果)。

源 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>
4

3 回答 3

16

您可以在代码中添加命名空间等等,但您可以有效地使用通配符命名空间。试试下面的 XPath 习惯用法。

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

name() 通常也可以工作,例如:

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

EDIT: Namespaces are great and i'm not suggesting they're not important, but wildcarding them comes in handy when cobbling together prototype code, one-off desktop tools, experimenting with XSLT, and so forth. Balance your need for convenience against acceptable risk for the task at hand. FYI, if need be, you can also strip or reassign namespaces.

于 2008-09-19T18:39:14.867 回答
2

文档中的标签最终位于由 xmlns 属性创建的“默认”命名空间中,没有前缀。不幸的是,仅 XPath 无法查询默认命名空间中的元素。我实际上不确定语义细节,但是您必须使用托管 XPath 的任何工具显式地将前缀附加到该名称空间。

在 .NET 中可能有更短的方法来执行此操作,但我见过的唯一方法是通过 NameSpaceManager。在显式添加命名空间后,您可以使用命名空间管理器进行查询,就好像命名空间元素中的所有标记都具有该前缀(我选择了“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);
        }
    }
}
于 2008-09-19T17:29:17.360 回答
1

您的问题与命名空间有关(xmlns="http://schemas.microsoft.com/developer/msbuild/2003")。您收到零节点是因为您没有使用命名空间对其进行限定。如果您删除 xmlns 属性,您的“//PropertyGroup”XPath 将起作用。如何使用命名空间进行查询通常涉及将默认 xmlns 别名为标识符(因为未在属性上指定一个),并选择类似“//myXMLNStoken:PropertyGroup”。

于 2008-09-19T16:49:03.977 回答