什么';我的XPath/XML有什么问题?
我正在尝试一个非常基本的XPath(如下所示),但没有找到任何东西。 我正在尝试.NET和,XPath(如什么';我的XPath/XML有什么问题?,xml,xpath,namespaces,Xml,Xpath,Namespaces,我正在尝试一个非常基本的XPath(如下所示),但没有找到任何东西。 我正在尝试.NET和,XPath(如//PropertyGroup、/PropertyGroup和//MSBuildCommunityTasksPath)对我来说根本不起作用(它们编译后返回零结果) 源XML: <?xml version="1.0" encoding="utf-8"?> <Project xmlns="http://schemas.microsoft.com/developer/msbuil
//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>
$(MSBuildProjectDirectory)\MSBuild.Community.Tasks\bin\Debug
您的问题在于名称空间(xmlns=”http://schemas.microsoft.com/developer/msbuild/2003"). 您收到的节点数为零,因为您没有使用名称空间对其进行限定。如果删除xmlns属性,则“//PropertyGroup”XPath将起作用。如何使用名称空间进行查询通常涉及将默认xmlns别名为标识符(因为属性上未指定标识符),并选择“//myXMLNStoken:PropertyGroup”之类的选项。文档中的标记最终位于xmlns属性创建的“默认”名称空间中,没有前缀。不幸的是,XPath本身无法查询默认名称空间中的元素。我实际上不确定语义细节,但您必须使用承载XPath的任何工具显式地将前缀附加到该名称空间
在.NET中可能有一种更短的方法来实现这一点,但我见过的唯一方法是通过名称空间管理器。显式添加命名空间后,可以使用命名空间管理器进行查询,就像命名空间元素中的所有标记都具有该前缀一样(我选择了“msbuild”):
使用系统;
使用System.Xml;
公共类XPathNamespace{
公共静态void Main(字符串[]args){
XmlDocument XmlDocument=新的XmlDocument();
xmlDocument.LoadXml(
@"
$(MSBuildProjectDirectory)\MSBuild.Community.Tasks\bin\Debug
");
XmlNamespaceManager namespaceManager=new
XmlNamespaceManager(xmlDocument.NameTable);
namespaceManager.AddNamespace(“msbuild”http://schemas.microsoft.com/developer/msbuild/2003");
foreach(xmlDocument.SelectNodes中的XmlNode(“//msbuild:msbuildcommunityttaskspath”,namespaceManager)){
Console.WriteLine(n.InnerText);
}
}
}
您可以在代码中添加名称空间等,但可以有效地对名称空间进行通配符。试试下面的XPath习惯用法
//*[local-name()='PropertyGroup']
//*[local-name()='MSBuildCommunityTasksPath']
name()通常也适用于以下情况:
//*[name()='PropertyGroup']
//*[name()='MSBuildCommunityTasksPath']
编辑:名称空间非常好,我并不是说它们不重要,但在拼凑原型代码、一次性桌面工具、试验XSLT等时,通配符很有用。平衡您的便利需求与手头任务的可接受风险。仅供参考,如果需要,您还可以剥离或重新分配名称空间。如果您可以提供一个简短的代码示例,说明您在.net中尝试过的内容,那么就可以更容易地指出可能出现的问题。谢谢!你不知道我寻找这个答案已经有多久了。太棒了@阿贝尔·莫雷洛斯——很高兴这有帮助;当我在许多月前终于发现这一点时,它使XML工作变得更加容易。取消资格是一件坏事。这相当于从RDBMS中请求列,而不指定哪些表。每个前缀声明的一行代码如何变成“以及所有这些”@grantwparks-我不是说名称空间没有价值,但有时有必要构建忽略它们的转换,有时不处理它们很方便。不管是什么情况,这个解决方案都会派上用场。数小时的搜索到此结束。非常感谢。
//*[name()='PropertyGroup']
//*[name()='MSBuildCommunityTasksPath']