Powershell脚本将xml标记设置为等于同一行上的另一个xml标记

时间:2017-02-22 19:35:30

标签: xml powershell xpath

让我先说一下我的powershell经验有限,并乐意接受我的需求替代申请。

我有一个xml文件,其中包含以下示例:

<!-- ... -->
<anElement tag1="A" tag2="B" tag3="0.00" tag4="2.00" />
<anotherElement tag1="C" tag2="B" tag3="0.00" tag4="2.00" />
<somethingElse tag1="D" tag2="B" tag3="0.00" tag4="2.00">maybe some text here?</somethingElse>
<!-- ... -->

我想要发生的是:

If tag1 = A or D
And tag2 = B
then set tag3 value = tag4 value

所以这将采用第1行和第3行并将tag3更新为2.00

我需要的完整代码是: 打开文件 执行编辑 保存文件

1 个答案:

答案 0 :(得分:0)

1)使用SelectNodes函数和相应的XPath语句,找到您想要更新的元素。

'//*[(./@tag1=''A'' or ./@tag1=''D'') and ./@tag2 = ''B'']'

上面的代码说找到任何属性tag1的元素'A''D',并且属性tag2的值为'B'

2)对于上面找到的每个元素,请为该元素的tag3属性指定其tag4属性的值。

| %{ #%{ is an alias (i.e. shorthand) for `| foreach-object`
    $_.tag3 = $_.tag4
}

完整解决方案(包含样本数据)

$xml = [xml]@"
<xml>
<something tag1="A" tag2="B" tag3="0.00" tag4="2.00" />
<something tag1="C" tag2="B" tag3="0.00" tag4="2.00" />
<something tag1="D" tag2="B" tag3="0.00" tag4="2.00" />
</xml>
"@
$xml.SelectNodes('//*[(./@tag1=''A'' or ./@tag1=''D'') and ./@tag2 = ''B'']') | %{
    $_.tag3 = $_.tag4
}


##Demo Output (function from https://blogs.msdn.microsoft.com/powershell/2008/01/18/format-xml/)
function Format-XML ([xml]$xml, $indent=2) 
{ 
    $StringWriter = New-Object System.IO.StringWriter 
    $XmlWriter = New-Object System.XMl.XmlTextWriter $StringWriter 
    $xmlWriter.Formatting = 'indented'
    $xmlWriter.Indentation = $Indent 
    $xml.WriteContentTo($XmlWriter) 
    $XmlWriter.Flush() 
    $StringWriter.Flush() 
    Write-Output $StringWriter.ToString() 
}
Format-XML $xml

<强>更新

我还注意到你提到从文件中读取XML并将其保存回文件...而在上面我直接为$xml变量分配了一个值,并显示了输出在屏幕上。

要从文件中读取XML,请使用$xml = [raw](get-content 'c:\path\to\file.xml' -raw)。更多信息(事实上,采用略有不同的方法):

要将XML保存回文件,只需使用$xml.Save('c:\path\to\file.xml')

即可

再次提供更多信息和替代方法: