古い記事
ランダムジャンプ
新しい記事
自分用メモ。
コマンドラインで XML を軽くいじる用途。
不完全な気がするけど、とりあえず当面の用途(Amazon API の XML)で使えているので放置。

*コード(xml2tsv.pl)
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Simple;
use utf8;
use open ":utf8";
binmode STDIN, ":utf8";
binmode STDOUT, ":utf8";

my $xml_str = join('', <>);

my $xs = new XML::Simple();

my $ref = $xs->XMLin($xml_str);

my @list = (["xml", $ref]);
while (my $rs = shift @list) {
    my ($label, $ri) = @$rs;
    my $rf = ref($ri);
    if ($rf eq "HASH") {
	foreach my $k (sort keys %{$ri}) {
	    push @list, ["$label/$k", $ri->{$k}];
	}
    } elsif ($rf eq "ARRAY") {
	for (my $i = 0; $i < @$ri; $i++) {
	    push @list, ["$label/\@".$i, $ri->[$i]];
	}
    } else {
	print qq($label\t$ri\n);
    }
}

*実行例
% head B00EOEZJ90.xml
<?xml version="1.0" ?><ItemLookupResponse ...
</HTTPHeaders>
<RequestId>...</RequestId>
<Arguments><Argument Name="AWSAccessKeyId" Value="..."></Argument>
<Argument Name="AssociateTag" Value="137439-22"></Argument>
<Argument Name="ItemId" Value="B00EOEZJ90"></Argument>
<Argument Name="Operation" Value="ItemLookup"></Argument>
<Argument Name="ResponseGroup" Value="Large,VariationMatrix"></Argument>
<Argument Name="Service" Value="AWSECommerceService"></Argument>
<Argument Name="Timestamp" Value="2018-08-23T08:01:24Z"></Argument>

% xml2tsv.pl B00EOEZJ90.xml | head
xml/xmlns	http://webservices.amazon.com/AWSECommerceService/2011-08-01
xml/OperationRequest/RequestId	...
xml/OperationRequest/RequestProcessingTime	0.1334097060000000
xml/Items/Item/ASIN	B00EOEZJ90
xml/Items/Item/DetailPageURL	...
xml/Items/Item/ParentASIN	B00LWHUW58
xml/Items/Item/SalesRank	109
xml/Items/Request/IsValid	True
xml/Items/Item/CustomerReviews/HasReviews	true
xml/Items/Item/CustomerReviews/IFrameURL	...