I now present you with a bit of code I've written in these past few days. Pay attention not to the code, but to the comment I put in the beginning:
# yeah, yeah, so there are several modules on CPAN to create XML from an hash ref
# it took me less time to write this code than to find the best module to do it for me
sub _hash2xml {
my ($tag_exterior, $ref, $indent) = (@_, 0);
my $xml;
if ( ref $ref eq 'HASH' ) {
if ( $tag_exterior ) {
$xml .= "<$tag_exterior>";
}
for ( keys %$ref ) {
$xml .= "\n " . " " x $indent . _hash2xml( $_, $ref->{$_}, $indent+1 );
}
if ( $tag_exterior ) {
$xml .= "\n" . " " x $indent
. "</$tag_exterior>";
}
}
elsif (ref $ref eq 'ARRAY' ) {
if ( $tag_exterior ) {
$xml .= "<$tag_exterior>";
}
for ( @$ref ) {
$xml .= _hash2xml( undef, $_, $indent );
}
if ( $tag_exterior ) {
$xml .= "\n" . " " x $indent
. "</$tag_exterior>";
}
}
else {
if ( $tag_exterior ) {
$xml .= "<$tag_exterior>" . $ref . "</$tag_exterior>";
}
else {
$xml .= $ref;
}
}
return $xml;
}
As a side note, the project was already using XML::Dumper, so first I looked into that. Unfortunately, I needed to export XML according to a specification, and XML::Dumper was creating attributes where I wanted tags, and doing a few other things with it I didn't want.
So I turned to XML::Simple. Unfortunately, it was creating an <opt>
tag around the XML and recording the XML to a file without me asking for it.
I did peruse the documentation of these two modules a bit...
I did search for XML modules on CPAN and saw a bunch of them I had already used in the past...
But then I thought: "ah, the hell with it... it's going to take me less time writing it myself than looking for the right module!"
And it did.
UPDATE: The Portuguese word for "exterior" (which in this case should probably be "outer") is the same as the English one. However, while in English you'd say "exterior tag", in Portuguese you say "tag exterior". That's the explanation of the name of the variable.
Re:escaping
cog on 2008-03-14T17:16:48
The data being exported is not likely to include <s, but just in case, I'll follow your suggestion. Thanks.