質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

Q&A

解決済

2回答

6844閲覧

複数の子要素を持つXMLを表形式に整形したい

can110

総合スコア38262

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

1グッド

0クリップ

投稿2017/02/23 05:13

編集2023/01/17 16:11

前提・実現したいこと

PowerShell(Win10x64上)にて.xmlファイルを入力、加工し.tsv(タブ区切り)出力しています。

入力XML(test.xml)

xml

1<?xml version="1.0" encoding="UTF-8"?> 2<results version="2"> 3 <errors> 4 <error id="unreadVariable"> 5 <location file="func.cpp" line="10"/> 6 </error> 7 <error id="redundantAssignment"> 8 <location file="main.cpp" line="36"/> 9 <location file="main.cpp" line="34"/> 10 </error> 11 </errors> 12</results>

XMLデータは、error要素内にlocation要素が1個以上、複数存在しえます。
このXMLからlocation.file, location.line, error.id 列で構成されたTSVを出力したいです。

試したこと

以下のようにいくつかSelectを試してみましたが、locationの内容が欠けたり、先頭の1文字しか出力できません。

PowerShell

1$xmlRes = [xml](Get-Content test.xml) 2 3# 方法1 : locationをそのまま出力 4# 結果 : 連結して出力される 5$res1 = $xmlRes.results.errors.error | Select @{Name="file"; Expression={$_.location.file}},@{Name="line"; Expression={$_.location.line}},id 6 7# 方法2 : location[0]を出力 8# 結果 : location1個だと、location列データが出力されない。 9$res2 = $xmlRes.results.errors.error | Select @{Name="file"; Expression={$_.location[0].file}},@{Name="line"; Expression={$_.location[0].line}},id 10 11# 方法3 : location.file[0], line[0]を出力 12# 結果 : location1個だと、先頭の1文字?しか出力されない。 13$res3 = $xmlRes.results.errors.error | Select @{Name="file"; Expression={$_.location.file[0]}},@{Name="line"; Expression={$_.location.line[0]}},id 14 15echo "res1---" 16echo ($res1 | Select file,line,id) 17$res1 | Export-Csv -Path res1.tsv -NoTypeInformation -Delimiter "`t" 18 19echo "res2---" 20echo ($res2 | Select file,line,id) 21$res2 | Export-Csv -Path res2.tsv -NoTypeInformation -Delimiter "`t" 22 23echo "res3---" 24echo ($res3 | Select file,line,id) 25$res3 | Export-Csv -Path res3.tsv -NoTypeInformation -Delimiter "`t"

実行結果

res1--- file line id ---- ---- -- func.cpp 10 unreadVariable {main.cpp, main.cpp} {36, 34} redundantAssignment res2--- unreadVariable main.cpp 36 redundantAssignment res3--- f 1 unreadVariable main.cpp 36 redundantAssignment

欲しい結果は以下のいずれかです。

# 結果1 : 先頭のlocationのみを出力 file line id ---- ---- -- func.cpp 10 unreadVariable main.cpp 36 redundantAssignment # 結果2 : locationまで展開して出力 file line id ---- ---- -- func.cpp 10 unreadVariable main.cpp 36 redundantAssignment main.cpp 34 redundantAssignment

補足情報

  • 元データは、CUI版cppcheckで出力したものです。
  • 方法1で作成できる.tsvは行列データずれもなくexcelで開けるので、できればといった感じの質問です。
kame-3👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

もう解決されたようですが、参考までに。

PowerShell

1$res1 = $xmlRes.results.errors.error | Foreach-Object { 2 $id = $_.id 3 $_.location | Foreach-Object { 4 $_ | 5 Add-Member NoteProperty id $id -PassThru | 6 Select-Object file, line, id 7 } 8}

投稿2017/02/23 13:10

Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2017/02/23 13:28

実行したところlocation毎に展開できました。 複雑そうな式ですが、パイプ毎に確認していけばなんとか理解できそうな気がします。 回答ありがとうございました。
guest

0

自己解決

$.location.file を $.FirstChild.file とすることで先頭のみのlocation要素の出力ができました。
(location要素が先頭に必ずあることが前提)

PowerShell

1$xmlRes = [xml](Get-Content test.xml) 2$res1 = $xmlRes.results.errors.error | Select @{Name="file"; Expression={$_.FirstChild.file}},@{Name="line"; Expression={$_.FirstChild.line}},id 3 4echo "res1---" 5echo ($res1 | Select file,line,id) 6$res1 | Export-Csv -Path res1.tsv -NoTypeInformation -Delimiter "`t"

結果

file line id ---- ---- -- func.cpp 10 unreadVariable main.cpp 36 redundantAssignment

投稿2017/02/23 06:26

can110

総合スコア38262

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問