Powershell根据其他键值更新xml键值

时间:2014-08-08 14:39:22

标签: xml powershell xpath

我正在尝试编写一些powershell,它将根据同一节点中另一个键值对的值更新xml键值对的值。示例xml:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 <plugins>
  <plugin pluginType="plugin1" polling_internal="2" polling_unit="M" enabled="true">
      <params>
        <add key="Server" value="server1.local" />
        <add key="database" value="databasename1" />
      </params>
    </plugin>
  <plugin pluginType="plugin2" polling_internal="2" polling_unit="M" enabled="true">
      <params>
        <add key="Server" value="server2.local" />
        <add key="database" value="databasename2" />
      </params>
    </plugin>
 </plugins>
</configuration>

真实文件中有数百个插件。我想查找名为databasename1 - <add key="database" value="databasename1"的所有数据库实例,并以服务器名称server2.local为例更新相应的服务器密钥。

我知道这可以用select-xml和xpath完成,但它超出了我。任何帮助都非常赞赏。

2 个答案:

答案 0 :(得分:1)

您可以使用此XPath根据您解释的标准获取所有value属性(xpath格式化以便于阅读):

//plugin
    /params[add[@key='database' and @value='databasename1']]
        /add[@key='Server']
            /@value

最复杂的部分(上面xpath中的第2行)表示搜索<params>节点带有条件:具有属性<add>的子节点key等于“数据库”和属性{{1 value等于“databasename1”。其余的与其他答案中的证明相似:

value

答案 1 :(得分:0)

这样的事情可以解决问题:

[Xml]$oXml = Get-Content oldfile.xml

$sXPath = "/configuration/plugins/plugin/params/add[@value='databasename1']"
$cChildren = $oXml.SelectNodes($sXPath)

foreach ($oChild in $cChildren) {
    $oParent = $oChild.get_ParentNode()
    $oServer = $oParent.ChildNodes | Where-Object { $_.key -eq "Server" }
    $oServer.value = "server2.local"
}

$oXml.OuterXml | Out-File newfile.xml

如果使用更复杂的XPath,则应该使用更少的代码。