2016-10-03 72 views
0

要在PowerShell中獲取XML元素的值,我們可以通過將元素視爲PowerShell對象的屬性來簡單地寫出路徑;即$xml.RootElement.ChildElement.GrandChild。然而,如果我們感興趣的元素有一個關聯的屬性,爲了獲得文本值,我們需要向下鑽取到文本節點;然後,即$xml.RootElement.ChildElement.GrandChild.'#text'在使用PowerShell從XML中獲取XML文本值時智能處理屬性

不幸的是,當元素沒有屬性時,我們不能使用文本節點;即在該情景中,$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 
+0

PS。我注意到在我的命令中加入'$ xmlElement.GetType()'表明元素的類型根據是否存在任何屬性而改變;即如果它是'XmlElement',如果沒有,則是'String' .. – JohnLBevan

回答

1

SelectNodes功能解決了這個問題:

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

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

工作爲EXPE反恐執行局。

它也可以以這種方式更新節點:

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>