Xml in Perl
use strict;
use warnings;
use XML::LibXML;
use Data::Dumper;
# Plant will be mapped to XML. We use XML::LibXML to handle XML operations.
# In Perl, we'll use a hash reference to represent the Plant structure.
sub new_plant {
my ($id, $name, @origin) = @_;
return {
id => $id,
name => $name,
origin => \@origin,
};
}
# Helper function to convert a plant hash to a string
sub plant_to_string {
my $p = shift;
return sprintf("Plant id=%d, name=%s, origin=[%s]",
$p->{id}, $p->{name}, join(' ', @{$p->{origin}}));
}
# Create a new XML document
my $doc = XML::LibXML::Document->new('1.0', 'UTF-8');
# Create a plant
my $coffee = new_plant(27, "Coffee", "Ethiopia", "Brazil");
# Create the plant element
my $plant = $doc->createElement('plant');
$plant->setAttribute('id', $coffee->{id});
$plant->appendTextChild('name', $coffee->{name});
for my $origin (@{$coffee->{origin}}) {
$plant->appendTextChild('origin', $origin);
}
# Add the plant to the document
$doc->setDocumentElement($plant);
# Print the XML
print $doc->toString(1); # The argument 1 enables pretty printing
# To add a generic XML header to the output, we can use XML declaration
print $doc->xmlDeclaration, "\n", $doc->toString(1);
# Parse XML back into a data structure
my $parsed_doc = XML::LibXML->load_xml(string => $doc->toString);
my $parsed_plant = $parsed_doc->documentElement();
my %p;
$p{id} = $parsed_plant->getAttribute('id');
$p{name} = $parsed_plant->findvalue('./name');
$p{origin} = [$parsed_plant->findnodes('./origin')];
@{$p{origin}} = map { $_->textContent } @{$p{origin}};
print plant_to_string(\%p), "\n";
# Create another plant
my $tomato = new_plant(81, "Tomato", "Mexico", "California");
# Create a nesting structure
my $nesting = {
plants => [$coffee, $tomato]
};
# Create a new document for the nesting structure
my $nesting_doc = XML::LibXML::Document->new('1.0', 'UTF-8');
my $nesting_root = $nesting_doc->createElement('nesting');
$nesting_doc->setDocumentElement($nesting_root);
my $parent = $nesting_doc->createElement('parent');
my $child = $nesting_doc->createElement('child');
$parent->appendChild($child);
$nesting_root->appendChild($parent);
for my $p (@{$nesting->{plants}}) {
my $plant = $nesting_doc->createElement('plant');
$plant->setAttribute('id', $p->{id});
$plant->appendTextChild('name', $p->{name});
for my $origin (@{$p->{origin}}) {
$plant->appendTextChild('origin', $origin);
}
$child->appendChild($plant);
}
print $nesting_doc->toString(1);
This Perl script demonstrates XML handling using the XML::LibXML
module, which provides similar functionality to Go’s encoding/xml
package. Here’s a breakdown of the translation:
We define a
new_plant
function to create a hash reference representing a plant, similar to thePlant
struct in Go.The
plant_to_string
function provides similar functionality to theString()
method in Go.We use
XML::LibXML::Document
to create and manipulate XML documents.The
createElement
,setAttribute
, andappendTextChild
methods are used to build the XML structure.We use
toString(1)
to generate indented XML output, similar toMarshalIndent
in Go.For parsing XML, we use
XML::LibXML->load_xml
and then extract data using DOM methods.The nesting structure is created in a similar way, building up the XML document using
createElement
andappendChild
.
This script provides equivalent functionality to the Go example, demonstrating XML creation, marshaling, unmarshaling, and nested structures in Perl.