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

Hello,

I need to change some data in an XML file.

To me this sounds something every programmer would know or need to learn how to do and it would be something that would be explained in numerous books and articles about Perl and XML. However what is usually explained is either how to create or how to parse XML, never how to replace data. Naturally i think i'm a little daft and i'm hoping that i'm not wasting anyone's time by asking this.

Given an XML file called db48844.opf, how would you change package/metadata/x-metadata/meta[\@name='dtb:totalTime']/\@content from 344 to 345?

Is this kind of change considered XSLT?

Replies are listed 'Best First'.
Re: Changing XML Data
by toolic (Bishop) on Sep 26, 2008 at 17:09 UTC
    There are Perl modules available on CPAN which can be used to replace data in XML files. One such module, XML::Twig, first parses the XML file, performs the replacements you request, then outputs new XML.

    As far as your specific question is concerned, I do not see any "344". Do you care to elaborate?

Re: Changing XML Data
by runrig (Abbot) on Sep 26, 2008 at 17:59 UTC
    If the file is not "too big" (e.g. mega gigabytes?) you can just use XML::LibXML:
    my $x = XML::LibXML->new; my $doc = $x->parse_file($file); my $root = $doc->getDocumentElement(); my ( $name, $content ) = qw(@name @content); for my $att ( $root->findnodes(qq[ //package/metadata/x-metadata/meta[$name='dtb:totalTime']/$content ]) ) { my $old_val = $att->value(); print "Changing value from $old_val to 345\n"; $att->setValue(345); } eval { $doc->toFile($file, 1) } or die "Could not write to $file: $@";
Re: Changing XML Data
by mirod (Canon) on Sep 26, 2008 at 18:45 UTC

    You could use XSLT, although I suspect that few XSLT processors can do streaming transformation (ie they would probably need to load the entire document in memory before starting to work), but 1 - I might be wrong and 2 - it may not matter.

    With XML::Twig you would write something like this (I am assuming here that content is an attribute of the meta element, as you did not show us the data you are working on):

    #!/usr/bin/perl use strict; use warnings; use XML::Twig; my $t= XML::Twig->new( twig_roots => { 'package/metadata/x-metadata/me +ta[@name="dtb:totalTime"]' # $_ is the current element => sub { $_->set_att( content = +> $_->att( 'content') +1); $_->print; } }, twig_print_outside_roots => 1, ) ->parsefile( 'package.xml');
Re: Changing XML Data
by boblawblah (Scribe) on Sep 26, 2008 at 17:08 UTC
    Well it's a 3 stop process - and you've already mentioned them. 1. You need to parse your xml file. 2. Change the data. 3. Create your new xml file (you can overwrite the one you read from). Viola, data replaced.