geekman has asked for the wisdom of the Perl Monks concerning the following question:

Hi! How can I modify a XML file with Perl? I have been using XML Simple to read the XML file, now I want to modify a value in it, but I can not do it. For example: My XML <xml> <computers> <os>Unix</os> </computers> </xml> How can I change the value Unix to Solaris. This is just an example. Help!! Thank you.

Replies are listed 'Best First'.
Re: Update XML data with Perl
by GrandFather (Saint) on Apr 30, 2009 at 05:43 UTC

    The 'kitchen sink' module is XML::Twig. With it you could:

    use strict; use warnings; use XML::Twig; my $xmlStr = <<END_XML; <xml> <computers> <os>Unix</os> </computers> </xml> END_XML my $twig = XML::Twig->new ( twig_roots => {'os' => \&newOs,}, twig_print_outside_roots => 1, ); $twig->parse ($xmlStr); sub newOs { my ($twig, $os) = @_; $os->set_text ('Solaris'); $os->print (); }

    Prints:

    <xml> <computers> <os>Solaris</os> </computers> </xml>

    True laziness is hard work
Re: Update XML data with Perl
by Your Mother (Archbishop) on Apr 30, 2009 at 05:48 UTC

    Gotta pick up some xpath but this is a great, fast, flexible, robust way to do it; XML::LibXML.

    use XML::LibXML; my $doc = XML::LibXML->new->parse_fh(\*DATA); my ( $os ) = $doc->findnodes('//os[text()="Unix"]'); my $content = $os->firstChild(); $content->setData("Solaris"); print $doc->serialize(1); __DATA__ <xml> <computers> <os>Unix</os> </computers> </xml>

    Ta.

    <?xml version="1.0"?> <xml> <computers> <os>Solaris</os> </computers> </xml>
Re: Update XML data with Perl
by zwon (Abbot) on Apr 30, 2009 at 18:39 UTC

    You can use XML::Simple not only to read XML, but also to write it back. Though I can't say it's so simple ;)

    use strict; use warnings; use XML::Simple; my $xml = '<xml> <computers> <os>Unix</os> </computers> </xml>'; my $ref = XMLin($xml); $ref->{computers}{os} = 'Solaris'; $xml = XMLout( $ref, RootName => 'xml', NoAttr => 1, NoIndent => 1 ); print "$xml\n"; __END__ <xml><computers><os>Solaris</os></computers></xml>
      Thanks for your answer. But now I have another problem. This works great!!, but how can I do the XMLout to a file? Thanks.

        Just wanted to mention that XML::LibXML has file reading and writing methods (as well as a bunch of other in/out methods):

        $state = $doc->toFile($filename, $format); $doc = $parser->parse_file( $xmlfilename );
        I found how to do this. Thanks.