使用Powershell在带有命名空间的XML中选择带有Xpath的属性

时间:2014-08-29 10:18:29

标签: xml powershell xpath

我有一个带有NLog节点的.Net配置文件:

<?xml version="1.0"?>
<configuration>
  <appSettings>
  </appSettings>
  <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <targets async="true">
      <target xsi:type="File" name="f" fileName="path to file" />
    </targets>
    <rules>
      <logger name="*" minlevel="Debug" writeTo="c,f" />
    </rules>
  </nlog>
</configuration>

我正在尝试使用Powershell更改target的{​​{1}}值。

我正在使用此代码:

fileName

我的XPath表达式为[xml]$xml = Get-Content $file $ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable) $ns.AddNamespace("ns", $namespace) # $namespace is `http://www.nlog-project.org/schemas/NLog.xsd` $values = $xml.selectNodes($xpath, $ns)

但是$值总是有0个结果。

有什么想法吗?我做错了什么?

谢谢!

1 个答案:

答案 0 :(得分:3)

在XML文档中,有一个默认命名空间

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd">

后代元素随后隐含地以此命名空间为前缀。但是,attributes do not take on a default namespace。换句话说,输入XML中的属性称为ns:fileName,但只有fileName。这同样适用于name属性。

//ns:nlog/ns:targets/ns:target[@name='f']/@fileName

根据XML的结构(及其可预测性),您可能希望将表达式缩短为

//ns:target[@name='f']/@fileName

要使初始XPath表达式起作用,输入XML必须如下所示:

<targets xmlns:ns="http://www.nlog-project.org/schemas/NLog.xsd" async="true">
  <target xsi:type="File" ns:name="f" ns:fileName="path to file" />
</targets>