2016-05-12 8 views
-1

ありがとうございます。私は未知の構造と異種要素のxmldocumentを持っています。私は、要素名を取得するすべての要素を反復処理したい、それがレジストリキーにXML文書を再構築し、最終的に値をだと値構造とサイズが不明なxmlツリーを繰り返します(xmlとレジストリの両方)

<Root> 
    <Names> 
    <Name>Bob</Name> 
    </Names> 
    <Locations> 
    <States> 
     <State>Ohio</State> 
     <State>Michigan</State> 
     <State> 
     Florida 
     <WeatherType>Hot</WeatherType> 
     </State> 
    </States> 
    </Locations> 
</Root> 

私が使用するXPathを(含まれる出力reg path)を各要素値(これはregキー値に使用します)に適用します。出力は次のようになります。

Root\Names\Name = Bob 
Root\Locations\States\State = Ohio 
Root\Locations\States\State = Michigan 
Root\Locations\States\State = Florida 
Root\Locations\States\State\Florida\WeatherType = Hot 

答えて

1

あなたが探している出力はxpathではありません。 Ex。 WeatherType - ノードのxpathはRoot/Locations/States/State[contains(text(),'Florida')]/WeatherTypeです。

は、私はこのようにそれに近づくでしょう、あなたが求めているものを取得するには親ノードのための
  • ゲットパステキスト値を持つすべてのノードを検索

      • テキスト値を追加します。同じ型(要素名)の兄弟が存在する場合はパスに、ex。州。
    1. 出力path = text-value

    例:

    #$xml = [xml](Get-Content -Path myfile.xml) 
    $xml = [xml]@" 
    <Root> 
        <Names> 
        <Name>Bob</Name> 
        </Names> 
        <Locations> 
        <States> 
         <State>Ohio</State> 
         <State>Michigan</State> 
         <State> 
         Florida 
         <WeatherType>Hot</WeatherType> 
         </State> 
        </States> 
        </Locations> 
    </Root> 
    "@ 
    
    #Get nodes with text-value 
    $nodesWithText = $xml.SelectNodes("//*[text()]") 
    
    foreach($node in $nodesWithText) { 
        #Start with end of path (element-name of the node with text-value) 
        $path = $node.LocalName 
        #Get parentnode 
        $parentnode = $node.ParentNode 
    
        #Loop until document-node (parent of root-node) 
        while($parentnode.LocalName -ne '#document') { 
    
         #If sibling with same LocalName (element-name) exists 
         if(@($parentnode.ParentNode.ChildNodes | Where-Object { $_.LocalName -eq $parentnode.LocalName }).Count -gt 1){ 
          #Add text-value to path 
          $path = "{0}\$path" -f ($parentnode.'#text').Trim() 
         } 
    
         #Add LocalName (element-name) for parent to path 
         $path = "$($parentnode.LocalName)\$path" 
    
         #Go to next parent node 
         $parentnode = $parentnode.ParentNode 
        } 
    
        #Output "path = text-value" 
        "$path = $(($node.'#text').Trim())" 
    } 
    

    出力:

    Root\Names\Name = Bob 
    Root\Locations\States\State = Ohio 
    Root\Locations\States\State = Michigan 
    Root\Locations\States\State = Florida 
    Root\Locations\States\State\Florida\WeatherType = Hot 
    
  • +0

    絶対に華麗な。清潔でシンプル。私は、各要素ごとに自分自身を呼び出す機能を持たなければならないと考えました。これはさらに優れています。答える時間をとってくれてありがとう! –

    +0

    ようこそ。個人的には、各ノードをパスに変換して再利用できるように関数内にラップします。次に、スクリプト内の "select text nodes"とforeach-loopだけを保持します。しかし、それは私の個人的な好みなので、私はそれを残しました。とにかくそれを変更するコードの4行だけ。 :-) –

    関連する問題