0

多くの属性と同じ名前の複数の要素を持つ XML データがあり、それを CSV ファイルにフラット化したいと考えています。データ XML は次のようになります。

<?xml version="1.0" encoding="utf-8"?>
<SEGMENTS>
    <SEGMENT NAME="webcluster">
        <RESULTPAGE>
            <RESULTSET FIRSTHIT="1" LASTHIT="100" HITS="100" TOTALHITS="100">
                <HIT NO="1" RANK="19000" SITEID="0" MOREHITS="100">
                    <FIELD NAME="rank">19000</FIELD>
                    <FIELD NAME="id">1</FIELD>
                    <FIELD NAME="url">C:\website.com\folder1\file1.txt</FIELD>
                    <FIELD NAME="filename">file1.txt</FIELD>
                    <FIELD NAME="path">https://website.com/folder1/</FIELD>
                </HIT>
                <HIT NO="2" RANK="19000" SITEID="0" MOREHITS="100">
                    <FIELD NAME="rank">19000</FIELD>
                    <FIELD NAME="id">2</FIELD>
                    <FIELD NAME="url">C:\website.com\folder1\file2.txt</FIELD>
                    <FIELD NAME="filename">file2.txt</FIELD>
                    <FIELD NAME="path">https://website.com/folder1/</FIELD>
                </HIT>
                <HIT NO="3" RANK="18999" SITEID="0" MOREHITS="100">
                    <FIELD NAME="rank">18999</FIELD>
                    <FIELD NAME="id">3</FIELD>
                    <FIELD NAME="url">C:\website.com\folder5\file3.txt</FIELD>
                    <FIELD NAME="filename">file3.txt</FIELD>
                    <FIELD NAME="path">C:\website.com\folder\</FIELD>
                </HIT>
            </RESULTSET>
        </RESULTPAGE>
    </SEGMENT>
</SEGMENTS>

そして、私はそれを繰り返して、このようなものを生成しようとしています

HIT    filename    path  
-----  ----------  ------  
1      file1.txt   C:\website.com\folder1\  
2      file2.txt   C:\website.com\folder1\  
3      file3.txt   C:\website.com\folder5\

私のコードは次のとおりです。

[xml]$xml=Get-Content .\xmlfile.xml  
$hits = $xml.segments.segment.resultpage.resultset.hit  
foreach($hit in $hits)  
{  
    foreach($field in $hit.field)  
    {  
        if (field."NAME" -eq 'url')  
        {  
            write-output $hit.no $field."#VALUE"  
        }  
    }  
}  

そして、エラーが発生し続けます。序数の位置 ($hits[0].field[4]) で参照することにより、さまざまな要素と属性にアクセスできますが、FIELD 値が異なる順序になる可能性がある将来の出力から保護したいと考えています。

誰かがこれを行う方法を提案できますか? select-XML を使用してみましたが、それはさらに面倒であることがわかりましたが、おそらくそれはより洗練された方法です。

4

3 に答える 3

1

私はそれが好きではありませんが、このような何かがそれを行うようです。

[xml]$xml=Get-Content .\xmlfile.xml  
$hits = $xml.segments.segment.resultpage.resultset.hit  
foreach($hit in $hits)  
{  
    $result = new-object PSObject -Property @{ hit = $hit.no; filename = ""; path = ""}

    foreach($field in $hit.field)  
    {  
        if ($field."NAME" -eq 'url')  
        {  
            $result.path = $field."#text"
        }  
        if ($field."NAME" -eq 'filename')
        {
            $result.filename = $field."#text"
        }
    }  
    write-output $result
}  

または、すべてのフィールドを取得してから、関連するものを選択します。

[xml]$xml=Get-Content .\xmlfile.xml  
$hits = $xml.segments.segment.resultpage.resultset.hit  
foreach($hit in $hits)  
{  
    $result = new-object PSObject -Property @{ hit = $hit.no }
    $hit.field | % { Add-Member -InputObject $result -MemberType NoteProperty -Name $_."NAME" -Value $_."#text"}  
    $result | select hit,url,filename | write-output
}  
于 2013-06-28T03:18:56.273 に答える
0

次のようなことを試してください:

Select-Xml -Xml $xml -XPath '//HIT' | Foreach {
    $num=$_.Node.NO
    $filenameAttr = $_.Node.Field | where {$_.Name -eq 'filename'}
    $pathAttr = $_.Node.Field | where {$_.Name -eq 'path'}
    new-object psobject -Property ([ordered]@{HIT=$num; filename = $filenameAttr.InnerText; path = $pathAttr.InnerText})
}
于 2013-06-28T03:22:22.430 に答える