我有成千上万个.XML文件,它们包含与以下内容相似的代码
<work-item>
<field id="assignee">
<list>
<item>John Doe</item>
<item>AZCDEF</item>
</list>
</field>...
我正在使用以下Powershell尝试获取“ item”节点的值。
$ files = Get-ChildItem-路径C:\ temp \ dev \ workitems \ -include workitem.xml -Recurse | %{$ 。FullName}$文件| foreach {$ Doc = [xml] $ MyXML =获取内容$写($ _)#write($ Doc.name)$ XMLNode = $ MyXML.SelectNodes('// field [@ id =“ assignee”] / list / item')
$XMLNode | foreach {
If ($_.'#text'.length -ne 6) {
write("Removing " + $_.'#text' + " From xml.")
[void]$_.ParentNode.RemoveChild($_)
}
}
$Doc.Save($_)
}
但是,保存文档时出现以下错误。方法调用失败,因为[System.Object []]不包含名为“保存”的方法。在C:\ ALM \ PowerShell脚本\删除错误的assignee.ps1:14 char:14+ $ Doc.Save <<<
问题是我似乎无法获得item节点的值(John Doe或AZCDEF),因此我可以检查其长度和第二个字符。
删除元素后如何保存文档?
PS> $xml = [xml] @"
<work-item>
<field id="assignee">
<list>
<item>John Doe</item>
<item>AZCDEF</item>
</list>
</field>
</work-item>
"@
PS> $nodes = $xml.SelectNodes('//field[@id="assignee"]/list/item')
PS> $nodes | foreach { write($_.InnerText) }
John Doe
AZCDEF
并且一旦获得字符串,您就可以过滤值-例如
PS> $nodes | where-object { ($_.InnerText.Length -le 2) -or ($_.InnerText[1] -ne 'Z') }
#text
-----
John Doe
请记住,字符串是零索引的,所以第二个字符是$_.InnerText[1]
...
所以现在我们有了一个表达式,该表达式可以过滤要删除的节点列表,我们可以将其通过管道传递到RemoveChild:
PS> $nodes ` | where-object { ($_.InnerText.Length -le 2) -or ($_.InnerText[1] -ne 'Z') } ` | foreach-object { $_.ParentNode.RemoveChild($_) } PS> $xml.OuterXml <work-item><field id="assignee"><list><item>AZCDEF</item></list></field></work-item>