ETOOBUSY 🚀 minimal blogging for the impatient
XML::Twig
TL;DR
A few notes about the XML::Twig that is useful to me (these days).
XML::Twig is amazing but the documentation can be a bit… daunting.
Fact is that it does a lot of things. It’s handy and it’s also amazing at providing means to deal with huge XML documents in all possibly flexible ways.
Anyway, this is not my use case. I need something that can grok XML and give me a reasonable way to deal with it. Another alternative I’ll look into is Mojo::DOM, but for today… XML::Twig.
This is my SYNOPSIS, which is a working copy-and-paste example of a subset of the whole API:
#!/usr/bin/env perl
use v5.24;
use warnings;
use XML::Twig;
my $twig = XML::Twig->new(pretty_print => 'indented');
#$twig->parsefile($filename);
#$twig->parse($xml_string);
$twig->parse(\*DATA);
say $twig->toString;
my ($collection) = $twig->findnodes('/result/collection');
say $collection->toString;
if ($collection->has_atts) { # yes it has
say "\ncollection has attributes:";
my @names = sort { $a cmp $b } $collection->att_names;
for my $name (@names) {
my $value = $collection->att($name);
say "'$name' -> '$value'";
}
my $attributes_hashref = $collection->atts;
say for keys $attributes_hashref->%*;
}
say '';
my @items = $twig->findnodes('//item');
my $item = pop @items;
say $item->tag, ' has ', $item->children_count, ' children';
say ' (it contains no attribute)' unless $item->has_atts;
for my $child ($item->children) {
say ' - ', $child->tag;
if ($child->has_children) {
say ' has children (', $child->children_count, ')';
my $grandchild = $child->first_child;
say ' that is text <', $grandchild->text, '>'
if $grandchild->is_text;
}
elsif ($child->is_empty) {
say ' is empty';
}
}
__END__
<?xml version = "1.0"?>
<result>
<collection what="ever" you="do">
<item>
<foo>This is foo</foo>
<bar/>
</item>
<item>
<foo>This is foo, too</foo>
<bar>This is arguably bar</bar>
<baz/>
</item>
</collection>
</result>
So… let’s run it:
$ perl xmltwig.pl
<?xml version="1.0"?>
<result>
<collection what="ever" you="do">
<item>
<foo>This is foo</foo>
<bar/>
</item>
<item>
<foo>This is foo, too</foo>
<bar>This is arguably bar</bar>
<baz/>
</item>
</collection>
</result>
<collection what="ever" you="do">
<item>
<foo>This is foo</foo>
<bar/>
</item>
<item>
<foo>This is foo, too</foo>
<bar>This is arguably bar</bar>
<baz/>
</item>
</collection>
collection has attributes:
'what' -> 'ever'
'you' -> 'do'
you
what
item has 3 children
(it contains no attribute)
- foo
has children (1)
that is text <This is foo, too>
- bar
has children (1)
that is text <This is arguably bar>
- baz
is empty
I hope it can be useful… stay safe anyway!