OK, so - XML::Simple
lies. It's not simple. It's for simple XML. And it's basically horrible, don't use it.
"The use of this module in new code is discouraged. Other modules are available which provide more straightforward and consistent interfaces."
I would suggest XML::Twig
instead:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig -> new ( 'pretty_print' => 'indented_a',
'twig_handlers' => { 'Row' => sub { $_ -> print } } );
$twig -> parsefile ( "yourXmlFile.xml" );
##print the whole thing, formatted:
$twig -> print;
Something like that. If you can give a desired input/output, then we can give you a better example to work from.
Edit: Based on your example given:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig->new(
'pretty_print' => 'indented_a',
'twig_handlers' => {
'Row' => sub {
print $_ ->first_child_text('product_id'), "\n";
print $_ ->first_child_text('product_name'), "\n";
}
}
);
$twig->parsefile("yourXmlFile.xml");
Although note - I've had to correct your XML. If that's because of a typing problem on your end (and I'm assuming it is because of the dots) that's fine. If you have broken XML on the other hand, then you're scuppered, because broken XML is supposed to be fatal, and anything that parses them is supposed to break.
Dealing with malformed XML
XML::Twig
allows you to set a handler that is called each time a particular element is seen. So in the example above, it's as simple as 'print every Row
element.
But you can set it to a subroutine:
'twig_handlers' => { 'Row' => \&process_row }
And then have a more detailed handler:
sub process_row {
my ( $twig, $row ) = @_;
print $row -> att{'name'},"\n";
print $row -> first_child('product_name')->text,"\n";
}
You can also use xpath
to find elements in your XML:
my $row23 = $twig -> get_xpath ( 'row[@name="23"]', 0 );
$row23 -> print;