use XML::LibXML qw(:all); my $parser = XML::LibXML->new(); # this could also be parse_string my $xmldom = eval { $parser->parse_file($file) }; if ($@) { # problem parsing, die $@, etc. } # this is the outermost element my $doc = $xmldom->documentElement; # the rest might be familiar if you've used # the DOM in JavaScript # findnodes is very useful, but hard to find # (look in XML::LibXML::Node); this assumes there's # XML like ...... my $xpath = 'asset/story'; # this can be whatever XPath my @story_nodes = $doc->findnodes($xpath); foreach my $story_node (@story_nodes) { my $id = $story_node->getAttribute('ID'); # this is an example where DOM can be annoying my ($uri_node) = $story_node->getChildrenByTagName('URI'); $uri_node->normalize(); my $uri = $uri_node->firstChild->getData(); # should 1st check it's ::Text ! $uri =~ s/^(http://)[^.]+(\.example\.)/$1new$2/; $uri_node->setData($uri; # .... } # another thing not so obvious, this is in ::Document # there are several variations, toFH, toString, etc.. $doc->toFile($newfile);