2016-05-19 14 views
1

xml-fileからすべてのウィンドウおよびすべてのビューポイントノードのname-attributesの値を抽出したいと思います。xml-nodesからpowershellを使用してネストされたループ

[XML]$doc = get-content -path 'W:\Demo1.xml' 


$objs = @() 
$dashboards = $doc.SelectNodes("//window[@class = 'dashboard']") 

foreach ($dashboard in $dashboards) 
{ 
    $worksheets = $dashboard.SelectNodes("//viewpoint[@name]") 

    foreach ($worksheet in $worksheets) 
    { 
     $obj = new-object psobject -prop @{Dashboard=$dashboard.name; Worksheet = $worksheet.name}; 
     $objs += $obj; 

    } 
} 

$objs 

私が期待したもの:

 
dashboard worksheet 
D1   V1 
D1   V2 
D1   V3 
D2   V10 
D2   V11 

私が得たもの:

<?xml version='1.0' encoding='utf-8' ?> 
     <workbook> 
      <windows> 
       <window class='dashboard' name='D1'> 
        <viewpoints> 
        <viewpoint name='V1'> </viewpoint> 
        <viewpoint name='V2'> </viewpoint> 
        <viewpoint name='V3'> </viewpoint> 
       </viewpoints> 
       </window> 
       <window class='dashboard' name='D2'> 
        <viewpoints> 
        <viewpoint name='V10'> </viewpoint> 
        <viewpoint name='V11'> </viewpoint> 
        </viewpoints> 
       </window> 
      </windows> 
     </workbook> 

この

は私が書いたコードです
 
dashboard worksheet 
D1   V1 
D1   V2 
D1   V3 
D1   V10 
D1   V11 
D1   V14 
D2   V1 
D2   V2 
D2   V3 
D2   V10 
D2   V11 
D2   V14 

ここで何が間違っていますか?結果はネストされたループがどのように機能するかについての私の理解とは完全に相反しています。

答えて

2

/という文字で始まるXPathは、ドキュメントのルートノードから始まることを意味します。コンテキストノードから相対XPathを作成するには、/の前に.を配置する必要があります。

だからあなたのコードは次のようになります。

[XML]$doc = get-content -path 'W:\Demo1.xml' 


$objs = @() 
$dashboards = $doc.SelectNodes("//window[@class = 'dashboard']") 

foreach ($dashboard in $dashboards) 
{ 
    $worksheets = $dashboard.SelectNodes(".//viewpoint[@name]") 

    foreach ($worksheet in $worksheets) 
    { 
     $obj = new-object psobject -prop @{Dashboard=$dashboard.name; Worksheet = $worksheet.name}; 
     $objs += $obj; 

    } 
} 

$objs 
+0

あなたは私の日を保存しました。ありがとうございました。私はエラーを見つけるために何時間も費やしています。ちょっとしたことがありません...... – Nylix

1

あなたはまた、それを簡素化し、ダッシュボード画面からすべてのviewpointのノードを選択するために、あなたのxpathを採用できます。

[XML]$doc = get-content -path 'W:\Demo1.xml' 

$objs = @() 
$worksheets = $doc.SelectNodes("//window[@class = 'dashboard']//viewpoint[@name]") 

foreach ($worksheet in $worksheets) 
{ 
    $obj = new-object psobject -prop @{Dashboard=$worksheet.ParentNode.ParentNode.name; Worksheet = $worksheet.name}; 
    $objs += $obj; 
} 

$objs 

そしてここxpathない溶液:

[XML]$doc = get-content -path 'W:\Demo1.xml' 

$objs = $doc.DocumentElement.windows.window | Where class -eq 'dashboard' | foreach { 
    $dashboardName = $_.name 
    $_.viewpoints.viewpoint | foreach { 
     new-object psobject -prop @{Dashboard=$dashboardName; Worksheet = $_.name} 
    } 
} 
+0

'$ dashboard'は定義されていません、そうですか? – har07

+0

Upps、あなたは正しいです - 私は自分の答えを修正しました(今は 'ParentNode'プロパティを使ってダッシュボードを取得しています)。また、分でxpathのない例を提供します。 –

+0

まあ、$ worksheets = $ doc.SelectNodes( "// window [@class = 'dashboard'] // viewpoint [@name]」という行はエラーを生成します。 (ドイツ語から翻訳:NULLである式のメソッドを呼び出すことはできません) – Nylix

関連する問題