XML::Writer
今まで使ったこと無かったけど、これは便利だ。
#!/usr/bin/perl use strict; use warnings; use IO::String; use XML::Beautify; use XML::Writer; my $osns = 'http://ns.opensocial.org/2008/opensocial'; my $buffer = IO::String->new; my $writer = XML::Writer->new( NAMESPACES => 1, ENCODING => 'utf-8', OUTPUT => $buffer, PREFIX_MAP => +{ $osns => '', } ); my $response = +{ startIndex => 1, itemsPerPage => 2, totalResults => 100, entry => [ +{ id => '34KJDCSKJN2HHF0DW20394', name => +{ unstructured => 'Jane Doe', }, gender => 'female', }, +{ id => 'VMK92BFH3DNWRYX39673DF', name => +{ unstructured => 'John Smith', }, gender => 'male', }, ], }; $writer->startTag( [ $osns, 'response' ] ); render_xml( $writer, $response ); $writer->endTag( [ $osns, 'response' ] ); $writer->end; my $formatter = XML::Beautify->new(); $formatter->indent_str(' '); my $xml = $formatter->beautify($buffer->string_ref); print $xml; $buffer->close; sub render_xml { my ( $writer, $data ) = @_; for my $field ( keys %$data ) { my $val = $data->{$field}; if ( ref $val eq 'HASH' ) { $writer->startTag($field); render_xml( $writer, $data->{$field} ); $writer->endTag($field); } elsif ( ref $val eq 'ARRAY' ) { for my $entry (@$val) { $writer->startTag('entry'); $writer->startTag('person'); render_xml( $writer, $entry ); $writer->endTag('person'); $writer->endTag('entry'); } } else { $writer->startTag($field); $writer->characters($val); $writer->endTag($field); } } }
みたいなコードを書くと、
<response xmlns="http://ns.opensocial.org/2008/opensocial"> <entry> <person> <name> <unstructured>Jane Doe</unstructured> </name> <id>34KJDCSKJN2HHF0DW20394</id> <gender>female</gender> </person> </entry> <entry> <person> <name> <unstructured>John Smith</unstructured> </name> <id>VMK92BFH3DNWRYX39673DF</id> <gender>male</gender> </person> </entry> <startIndex>1</startIndex> <itemsPerPage>2</itemsPerPage> <totalResults>100</totalResults> </response>
って感じで出力される。