我在这里过去几个小时,博客和互联网上进行了广泛的研究。但是,到目前为止,我没有尝试过任何事情。 我所拥有的是使用以下命名空间生成的xml文件:
<DeploymentReport xmlns="http://schemas.microsoft.com/sqlserver/dac/DeployReport/2012/02">
我无法控制此文件的生成过程。据我了解,XPath的一个常见问题是不能使用命名空间,除非它们已经注册或删除。我宁愿不对xml文档进行任何修改,并认为以某种方式让它忽略它会更好。
我已尝试使用/name()=
并尝试在我的Xpath查询中使用local-name
(其基本版本为):
//Operations/Operation/Item[@Type!='SqlIndex' and not(contains(@Value, 'Export'))]
但是,这些方法都不起作用。或许,因为我使用Powershell版本3,如果这很重要吗?
我不希望注册命名空间的原因是因为它绑定到本地安装的Sql版本(该文件将使用该版本生成)。这意味着它会导致任何其他版本的问题。我不想注册其中的很多内容,并猜测它们将来会适应哪些内容。
如果有人可以提出一个处理这种情况的好方法,我将不胜感激?或者我没有希望,但是要注册命名空间并使其与每个Sql版本保持同步?
答案 0 :(得分:0)
使用local-name()
应该有效(包装是为了便于阅读):
//*[local-name()='Operations']
/*[local-name()='Operation']
/*[local-name()='Item'][@Type!='SqlIndex' and not(contains(@Value, 'Export'))]
答案 1 :(得分:0)
XPath并不适用于名称空间。它根本不是很方便,这就是全部。
如果您可以设法定义名称空间前缀,如
xmlns:s="http://schemas.microsoft.com/sqlserver/dac/DeployReport/2012/02"
然后很容易解决你的Xml元素。那么你的XPath表达式将是:
//s:Operations/s:Operation/s:Item[@Type!='SqlIndex' and not(contains(@Value, 'Export'))]
如果在您的上下文中无法声明命名空间前缀,那么您就会遇到麻烦。
然后将完整表达式(为了可读性而包装):
//*[local-name()='Operations'][namespace-uri()='http://schemas.microsoft.com/sqlserver/dac/DeployReport/2012/02']
/*[local-name()='Operation'][namespace-uri()='http://schemas.microsoft.com/sqlserver/dac/DeployReport/2012/02']
/*[local-name()='Item'][namespace-uri()='http://schemas.microsoft.com/sqlserver/dac/DeployReport/2012/02']
[@Type!='SqlIndex' and not(contains(@Value, 'Export'))]
当然,如果省略[namespace-uri()='http://schemas.microsoft.com/sqlserver/dac/DeployReport/2012/02']
,它仍然可以工作,但是如果你的Xml文档中有任何名称,你可能会意外地在不同的命名空间中处理具有相同名称的元素。
在更高版本的XPath中,您也可以使用
//*:Operations/*:Operation/*:Item[@Type!='SqlIndex' and not(contains(@Value, 'Export'))]
忽略命名空间。