如何获得“项目”节点的值

时间:2019-12-10 13:03:50

标签: xml powershell nodes selectnodes

我有成千上万个.XML文件,它们包含与以下内容相似的代码:

<work-item>
    <field id="assignee">
        <list>
            <item>John Doe</item>
            <item>AZCDEF</item>
        </list>
    </field>...

我正在使用以下Powershell尝试获取“ item”节点的值:

$files = Get-ChildItem -Path C:\temp\dev\workitems\ -include workitem.xml -Recurse | % { $_.FullName }
$files | foreach {
    $Doc = [xml]$MyXML = Get-Content $_
    write($_)
    #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 []]不包含名为“ Save”的方法。   在C:\ ALM \ PowerShell脚本\删除错误的assignee.ps1:14 char:14   + $ Doc.Save <<<<($ _)
      + CategoryInfo:InvalidOperation:(Save:String)[],RuntimeException       + FullyQualifiedErrorId:MethodNotFound

问题是我似乎无法获得item节点的值(John Doe或AZCDEF),因此可以检查其长度和第二个字符。

删除元素后如何保存文档?

2 个答案:

答案 0 :(得分:0)

要获取节点的文本内容(包括所有子节点),可以使用InnerText属性:

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>

答案 1 :(得分:0)

我使用以下代码使其正常工作。

sentimentals = ['negative' if x <= 2 else 'positive' for x in ratings['rating']]