2016-10-03 5 views
0

PowerShellでXML要素の値をフェッチするには、elemntsをPowerShellオブジェクトのプロパティであるかのように扱います。すなわち$xml.RootElement.ChildElement.GrandChildPowerShellを使用してxmlテキスト値をXMLからフェッチするときに属性をインテリジェントに処理する

しかし、関心のある要素に属性が関連付けられている場合は、テキスト値を取得するためにテキストノードにドリルダウンする必要があります。すなわち$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 
+0

PS。私は '$ xmlElement.GetType()'を私のコマンドに追加すると、属性の有無に応じて要素の型が変わることに気付きました。すなわち、もしそれらが 'XmlElement'であれば、それがなければ' String'です。 – JohnLBevan

答えて

1

SelectNodes機能は、この問題を回避します:EXPEとして

すなわち

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

または

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

仕事cted。

それは、このようにノードを更新することも可能です:

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> 
関連する問題