2 # Copyright (c) 1998 Jonathan Eisenzopf <eisen@pobox.com>
3 # XML::DumperISO is free software. You can redistribute it and/or
4 # modify it under the same terms as Perl itself.
6 package XML::DumperISO;
10 use vars qw($VAR1 $VERSION);
18 return bless $self,$class;
23 return $obj->pl2xml_string($ref);
36 my ($ref, $indent) = @_;
40 if (defined(ref($ref)) && (ref($ref) eq 'SCALAR')) {
41 $string .= "\n" . " " x $indent . "<scalarref>" . &QuoteXMLChars($$ref) . "</scalarref>";
45 elsif (defined(ref($ref)) && (ref($ref) eq 'HASH')) {
46 $string .= "\n" . " " x $indent . "<hash>";
48 foreach my $key (keys(%$ref)) {
49 $string .= "\n" . " " x $indent . "<item key=\"" . &QuoteXMLChars($key) . "\">";
50 if (ref($ref->{$key})) {
51 $string .= &Tree2XML($ref->{$key}, $indent+1);
52 $string .= "\n" . " " x $indent . "</item>";
54 $string .= &QuoteXMLChars($ref->{$key}) . "</item>";
58 $string .= "\n" . " " x $indent . "</hash>";
62 elsif (defined(ref($ref)) && (ref($ref) eq 'ARRAY')) {
63 $string .= "\n" . " " x $indent . "<array>";
65 for (my $i=0; $i < @$ref; $i++) {
66 $string .= "\n" . " " x $indent . "<item key=\"$i\">";
67 if (ref($ref->[$i])) {
68 $string .= &Tree2XML($ref->[$i], $indent+1);
69 $string .= "\n" . " " x $indent . "</item>";
71 $string .= &QuoteXMLChars($ref->[$i]) . "</item>";
75 $string .= "\n" . " " x $indent . "</array>";
80 $string .= "\n" . " " x $indent . "<scalar>" . &QuoteXMLChars($ref) . "</scalar>";
90 $_[0] =~ s/'/'/g;
91 $_[0] =~ s/"/"/g;
98 ## Skip enclosing "perldata" level
99 my $TopItem = $tree->[1];
100 my $ref = &Undump($TopItem);
106 ## Takes a parse tree of the XML generated by pl2xml, and recursively
107 ## undumps it to create a data structure in memory. The top-level
108 ## object is a scalar, a reference to a scalar, a hash, or an array.
109 ## Hashes and arrays may themselves contain scalars, or references to
110 ## scalars, or references to hashes or arrays, with the exception that
111 ## scalar values are never "undef" because there's currently no way to
112 ## represent undef in the dumped data.
120 for ($i = 1; $i < $#$Tree; $i+=2) {
121 if (lc($Tree->[$i]) eq 'scalar') {
122 ## Make a copy of the string
123 $ref = $Tree->[$i+1]->[2];
126 if (lc($Tree->[$i]) eq 'scalarref') {
127 ## Make a ref to a copy of the string
128 $ref = \ "$Tree->[$i+1]->[2]";
130 } elsif (lc($Tree->[$i]) eq 'hash') {
133 for ($j = 1; $j < $#{$Tree->[$i+1]}; $j+=2) {
134 next unless $Tree->[$i+1]->[$j] eq 'item';
135 my $ItemTree = $Tree->[$i+1]->[$j+1];
136 next unless defined(my $key = $ItemTree->[0]->{key});
137 $ref->{$key} = &Undump($ItemTree);
140 } elsif (lc($Tree->[$i]) eq 'array') {
143 for ($j = 1; $j < $#{$Tree->[$i+1]}; $j+=2) {
144 next unless $Tree->[$i+1]->[$j] eq 'item';
145 my $ItemTree = $Tree->[$i+1]->[$j+1];
146 next unless defined(my $key = $ItemTree->[0]->{key});
147 $ref->[$key] = &Undump($ItemTree);
150 } elsif (lc($Tree->[$i]) eq '0') {
151 $FoundScalar = $Tree->[$i + 1] unless defined $FoundScalar;
153 ## Unrecognized tag. Just move on.
157 ## If $ref is not set at this point, it means we've just
158 ## encountered a scalar value directly inside the item tag.
160 $ref = $FoundScalar unless defined($ref);
167 ### Tests the conversion of perl data structures into XML and back again
171 ### perl -e 'use XML::DumperISO; &XML::DumperISO::TestRoundTrip();'
173 ### The 5 sets of sample data below show some typical cases:
188 <scalarref>Hi Mom</scalarref>
195 <item key="key1">value1</item>
196 <item key="key2">value2</item>
204 <item key="0">foo</item>
205 <item key="1">bar</item>
213 <item key="0">Scalar</item>
215 <scalarref>ScalarRef</scalarref>
219 <item key="0">foo</item>
220 <item key="1">bar</item>
225 <item key="key1">value1</item>
226 <item key="key2">value2</item>
237 foreach $TestData (@$TestRuns)
242 my $Parser = XML::Parser->new(Style => 'Tree');
243 my $Tree = $Parser->parse($TestData);
245 my $DumperISO = new XML::DumperISO();
246 my $Ref = $DumperISO->xml2pl($Tree);
248 my $ReDump = $DumperISO->pl2xml_string($Ref);
250 if ($TestData eq $ReDump)
252 print STDERR ("Test $TestNum: Success.\n\n" .
254 &Data::Dumper::Dumper($Ref) .
259 print STDERR ("TestRoundTrip: data doesn't match!\n\n" .
260 "Orig:\n$TestData\nRound Trip:\n$ReDump\n");
272 XML::DumperISO - Perl module for dumping Perl objects from/to XML
276 # Convert Perl code to XML
278 my $dump = new XML::DumperISO;
283 email => 'eisen@pobox.com'
288 email => 'larry@wall.org'
291 $xml = $dump->pl2xml($perl);
294 # Convert XML to Perl code
296 my $dump = new XML::DumperISO;
305 # load Perl data structure from dumped XML
306 $data = $dump->xml2pl($Tree);
310 XML::DumperISO dumps Perl data to a structured XML format.
311 XML::DumperISO can also read XML data that was previously dumped
312 by the module and convert it back to Perl.
314 This is done via the following 2 methods:
315 XML::DumperISO::pl2xml
316 XML::DumperISO::xml2pl
320 Jonathan Eisenzopf <eisen@pobox.com>
324 Chris Thorman <ct@ignitiondesign.com>
325 L.M.Orchard <deus_x@pobox.com>
326 DeWitt Clinton <dewitt@eziba.com>
330 perl(1), XML::Parser(3).