Search notes:

Perl module XML::XPath

#!/usr/bin/perl
use warnings;
use strict;

use XML::XPath;

my $xml = qq{
<root attrib="hello world">
  <lvl_one id="id_a">foo</lvl_one>
  <lvl_one id="id_b">bar <lvl_two>two</lvl_two></lvl_one>
  <lvl_one id="id_b">baz <lvl_two>TWO<lvl_three>THREE</lvl_three></lvl_two></lvl_one>
  <xyz>Eggs, why and z</xyz>
</root>
};

my $xp = XML::XPath->new(xml => $xml);

printf "/root/\@attrib    : %s\n", $xp->findvalue  ('/root/@attrib'   ); # hello world
printf "/root//lvl_three : %s\n" , $xp->getNodeText('//lvl_three'     ); # THREE

my @lvl_one_nodes = $xp->findnodes('/root/lvl_one');
#  @lvl_one_nodes is an array of XML::Path::Node::Element

print "\nIterating over elements of /root/lvl_one\n";
for my $lvl_one_node (@lvl_one_nodes) {
  printf "  lvl_one_node: %s\n", $lvl_one_node->toString();
}

print "\nSame thing, but without recursing\n";
for my $lvl_one_node (@lvl_one_nodes) {
  printf "  lvl_one_node: %s\n", $lvl_one_node->toString(1);
}

print "\nExtracting ids\n";
for my $lvl_one_node (@lvl_one_nodes) {
  printf "  \@id %s\n", $lvl_one_node->findvalue('@id');
}
Github repository PerlModules, path: /XML/XPath/script.pl

Select tag with specfific attribute value

#!/usr/bin/perl
use warnings;
use strict;

use XML::XPath;

my $xml  = qq{
<root>
  <abc id='foo'>Hello</abc>
  <abc id='bar'>World</abc>
  <abc id='baz'>42</abc>
</root>
};

my $xp = XML::XPath->new(xml => $xml);

my $val = $xp->getNodeText('/root/abc[@id="bar"]');
print "val = $val\n"; # val = World
Github repository PerlModules, path: /XML/XPath/select-tag-with-specific-attribute-value.pl

getAttribute

#!/usr/bin/perl
use warnings;
use strict;

use XML::XPath;

my $xml  = qq{
<root>
  <abc id='one' desc='bla bla'  >Hello</abc>
  <abc id='two' desc='yada yada'>World</abc>
</root>
};

my $xp = XML::XPath->new(xml => $xml);
my ($node) = $xp->findnodes('/root/abc[@id="two"]');

print $node->getAttribute('desc'), "\n"; # yada yada
Github repository PerlModules, path: /XML/XPath/getAttribute.pl

setAttribute

#!/usr/bin/perl
use warnings;
use strict;

use XML::XPath;

my $xml  = qq{
<root>
  <abc id='one'   desc='bla bla'  >Hello</abc>
  <abc id='two'   desc='yada yada'>World</abc>
  <abc id='three' desc='etc.'     >42   </abc>
</root>
};

my $xp = XML::XPath->new(xml => $xml);
my ($node) = $xp->findnodes('/root/abc[@id="two"]');

# Change 'yada yada' to 'changed'
print $node->setAttribute('desc', 'changed');

print $xp->findnodes_as_string('/');
Github repository PerlModules, path: /XML/XPath/setAttribute.pl

removeAttribute

#!/usr/bin/perl
use warnings;
use strict;

use XML::XPath;

my $xml  = qq{
<root>
  <abc id='one'                      >Hello</abc>
  <abc id='two'   superflous='extra' >World</abc>
  <abc id='three'                    >42   </abc>
</root>
};

my $xp = XML::XPath->new(xml => $xml);
my ($node) = $xp->findnodes('/root/abc[@id="two"]');

print $node->removeAttribute('superflous');

print $xp->findnodes_as_string('/');
Github repository PerlModules, path: /XML/XPath/removeAttribute.pl

appendAttribute

#!/usr/bin/perl
use warnings;
use strict;

use XML::XPath;

my $xml  = qq{
<root>
  <abc id='one'   >Hello</abc>
  <abc id='two'   >World</abc>
  <abc id='three' >42   </abc>
</root>
};

my $xp = XML::XPath->new(xml => $xml);
my ($node) = $xp->findnodes('/root/abc[@id="two"]');


my $newAttribute = XML::XPath::Node::Attribute->new('new', 'value');
print $node->appendAttribute($newAttribute);

my $attr_specialChars = XML::XPath::Node::Attribute->new('one-two-three', '"one & two >= three"');
print $node->appendAttribute($attr_specialChars);

print $xp->findnodes_as_string('/');
Github repository PerlModules, path: /XML/XPath/appendAttribute.pl
Note how & and > are escaped.

Select any attribute value of a tag with a specific attribute value

#!/usr/bin/perl
use warnings;
use strict;

use XML::XPath;

my $xml  = qq{
<root>
  <abc id='foo' access='read'      >Hello</abc>
  <abc id='bar' access='read/write'>World</abc>
  <abc id='baz' access='none'      >42</abc>
</root>
};

my $xp = XML::XPath->new(xml => $xml);

my $access = $xp->getNodeText('/root/abc[@id="bar"]/@access');
print "access = $access\n"; # access = read/write
Github repository PerlModules, path: /XML/XPath/select-attribute-value-of-tag-with-specific-attribute-value.pl

Update attribute value

#!/usr/bin/perl
use warnings;
use strict;

use XML::XPath;

my $xml  = qq{
<root>
  <abc id='foo' access='read'      >Hello</abc>
  <abc id='bar' access='read/write'>World</abc>
  <abc id='baz' access='none'      >42</abc>
</root>
};

my $xp = XML::XPath->new(xml => $xml);

$xp->setNodeText('/root/abc[@id="bar"]/@access', 'all');

print $xp->findnodes_as_string('/');
Github repository PerlModules, path: /XML/XPath/update-attribute-value.pl

Insert a node

#!/usr/bin/perl
use warnings;
use strict;

use XML::XPath;

my $xml  = qq{
<root>
  <abc id='foo' access='read'      >Hello</abc>
  <abc id='bar' access='read/write'>World</abc>
</root>
};

my $xp = XML::XPath->new(xml => $xml);

my $new_node    = XML::XPath::Node::Element->new('abc');
my $node_text   = XML::XPath::Node::Text->new('foo');
my $attr_id     = XML::XPath::Node::Attribute->new('id');
my $attr_access = XML::XPath::Node::Attribute->new('access');

$attr_id     -> setNodeValue('baz');
$attr_access -> setNodeValue('all');

$new_node->appendChild($node_text);
$new_node->appendAttribute($attr_id);
$new_node->appendAttribute($attr_access);


#
# findnodes returns a XML::XPath::NodeSet, but for the appendChild
# below, we're instersted in an XML::XPath::Node:Element.
# Therefore, the $root is enclosed in paranthesis:
#
my ($root) = $xp->findnodes('/root');

$root->appendChild($new_node);

print $xp->findnodes_as_string('/');
Github repository PerlModules, path: /XML/XPath/add-tag.pl

Print part of the XML

The toString() method returns the entire text of a node:
#!/usr/bin/perl
use warnings;
use strict;


use XML::XPath;

my $xml  = qq{
<root>
  <abc id='1'><foo attr='x'>One  </foo></abc>
  <abc id='2'><foo attr='y'>Two  </foo></abc>
  <abc id='3'><foo attr='z'>Trhee</foo></abc>
</root>
};

my $xp = XML::XPath->new(xml => $xml);

my ($node) = $xp->findnodes('/root/abc[@id=2]');
print $node->toString();
Github repository PerlModules, path: /XML/XPath/toString.pl

Add a tag or modify a tag's attribute

#!/usr/bin/perl
use warnings;
use strict;

use XML::XPath;

my $xml  = qq{
<root>
  <abc id='foo' access='read'      >Hello</abc>
  <abc id='bar' access='read/write'>World</abc>
</root>
};

my $xp = XML::XPath->new(xml => $xml);

add_or_modify_tag('bar', 'none');
add_or_modify_tag('baz', 'all' );

sub add_or_modify_tag {

  my $abc_id     = shift;
  my $access_new = shift;

  my ($node) = $xp->findnodes(sprintf '/root/abc[@id="%s"]', $abc_id);

  if ($node) {
    $node->setAttribute('access', $access_new);
  }
  else {
    my $new_node    = XML::XPath::Node::Element->new('abc');
    my $new_attr    = XML::XPath::Node::Attribute->new('id'    , $abc_id    );

    $new_node->setAttribute('access', $access_new);
    $new_node->appendAttribute($new_attr);

    my ($root) = $xp->findnodes('/root');
    $root->appendChild($new_node);

  }
}

print $xp->findnodes_as_string('/');
Github repository PerlModules, path: /XML/XPath/add-or-modify-tag.pl

See also

XPath
Perl modules

Index