使用PowerShell从XML获取xml文本值时智能处理属性

时间:2016-10-03 14:17:46

标签: xml powershell xpath powershell-v4.0 xml-attribute

要在powershell中获取XML元素的值,我们可以通过将elemnts视为PowerShell对象的属性来简单地写出路径;即$xml.RootElement.ChildElement.GrandChild

但是,如果我们感兴趣的元素具有关联的属性,要获取文本值,我们需要向下钻取到文本节点;即$xml.RootElement.ChildElement.GrandChild.'#text'

遗憾的是,当元素没有属性时,我们无法使用文本节点;即在那种情况下,$xml.RootElement.ChildElement.GrandChild.'#text' 不起作用

Clear-Host
$example = [xml](@"
<demo>
    <element attribute='1'>10</element>
    <element>20</element>
</demo>
"@)

"just the element"
$example.demo.element 
"element's text"
$example.demo.element.'#text' 

我已为此编写了一个讨厌的解决方法,但怀疑这是错误的方法/ PowerShell有更优雅的方法来解决此问题。

我讨厌的解决方法:

function Get-TextNode {
    [CmdletBinding()]
    param (
        [Parameter(ValueFromPipeline = $true)]
        $xmlElement
    )
    process {
        if($xmlElement.Attributes.Count -eq 0) {
            $xmlElement
        } else {
            $xmlElement.'#text'
        }
    }
}

$example.demo.element | Get-TextNode 

1 个答案:

答案 0 :(得分:1)

SelectNodes函数适用于此问题:

$example.SelectNodes('/demo/element').'#text'

$example.SelectNodes('/demo/element/text()').Value

按预期工作。

也可以通过这种方式更新节点:

Clear-Host

$example = [xml](@"
<demo>
    <x>5</x>
    <element attribute='1'>10</element>
    <element>20</element>
</demo>
"@)

$example.OuterXml
#Result: <demo><x>5</x><element attribute="1">10</element><element>20</element></demo>

$example.SelectNodes('/demo/element/text()') | %{ 
    $_.value = $_.ParentNode.ParentNode.SelectSingleNode('./x/text()').Value  
}

$example.OuterXml
#Result: <demo><x>5</x><element attribute="1">5</element><element>5</element></demo>