问题
I'm trying to write some powershell that will update the value of a xml key value pair based on the value of another key value pair in the same node. Example 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>
The real file has hundreds of plugins in it. I want to find all instances of databases called databasename1 - <add key="database" value="databasename1"
and update the corresponding Server key with server name server2.local for example.
I know this can be done with select-xml and xpath, but its beyond me. Any assistance much appreciated.
回答1:
You can use this XPath to get all value
attribute according to the criteria you explained (xpath formatted for readability) :
//plugin
/params[add[@key='database' and @value='databasename1']]
/add[@key='Server']
/@value
The most complicated part (line 2 in above xpath) means search <params>
node with criteria : has child node <add>
having attribute key
value equals "database" and attribute value
value equals "databasename1". The rest is similar to what demonstrated in the other answer :
[XML]$xml = #load XML file
$xpath = "/configuration/plugins/plugin/params[add[@value='databasename1' and @key ='database']]/add[@key='Server']/@value"
$nodes = $xml.SelectNodes($xpath)
foreach ($n in $nodes) {
$n.value = "server2.local"
}
#save XML back to file
回答2:
Something like this should do the trick:
[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
Should be doable with less code if you use a more complex XPath.
来源:https://stackoverflow.com/questions/25206036/powershell-update-xml-key-value-based-on-other-key-value