ankit.tayal560 has asked for the wisdom of the Perl Monks concerning the following question:

I've written this code but the modifications are not reflecting in the xml file.am I missing something important in the code? confused about using perl in xml! would be glad if someone can help and explain in a detailed manner how to perform this task? I am getting output as Joey 67890

use strict; use warnings; use Data::Dumper; use XML::DOM; my $parser=new XML::DOM::Parser; my $doc=$parser->parsefile('C:\perl\perl_tests\xmlin.xml') or die$!; my $root=$doc->getDocumentElement(); my @address=$root->getElementsByTagName("address"); foreach my $address(@address) { if($address->getAttribute("name") eq "tayal") { if($address->getAttribute("id")=='70889') { $address->setAttribute("name","Joey"); $address->setAttribute("id","67890"); my $temp1=$address->getAttribute("name"); my $temp2=$address->getAttribute("id"); print("$temp1\t$temp2\n\n"); } } } XML FILE : <config logdir="var/log/foo/" debugfile="tmp/foo.debug"> <server name ="sahara" osname ="solaris" osversion="2.6"> <address name="ankit" id="70888"/> <address name="tayal" id="70889"/> </server> <server name="gobi" osname="irix" osversion="6.5"> <address name="anshul" id="70689"/> </server> <server name="kalahari" osname="linus" osversion="2.0.34"> <address name="raghu" id="45678"/> <address name="lucky" id="67895"/> </server> </config>

Replies are listed 'Best First'.
Re: How to modify an XML file using XML::DOM
by afoken (Chancellor) on Sep 28, 2016 at 05:54 UTC

    You read the file into memory, and you modify the in-memory copy. Now, what is required to make the changes appear in the file?

    Hint: It's the same problem that every simple editor program has, and most editors are smart enough to ask you. Start the editor, open a text file, modify the copy in the editor's part of memory. Exit the editor. What does the editor ask you when attempting to exit?

    Second hint: Read the synopsis of XML::DOM.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

      Okay, Got your point. I should write the contents into my xml file to see the changes. I tried this and gave me an error : can't call method "getEncoding" on an undefined value ...

      MODIFIED CODE : use strict; use warnings; use Data::Dumper; use XML::DOM; my $parser=new XML::DOM::Parser; my $doc=$parser->parsefile('C:\perl\perl_tests\xmlin.xml') or die$!; my $root=$doc->getDocumentElement(); my @address=$root->getElementsByTagName("address"); foreach my $address(@address) { if($address->getAttribute("name") eq "tayal") { if($address->getAttribute("id")=='70889') { $address->setAttribute("name","Joey"); $address->setAttribute("id","67890"); my $temp1=$address->getAttribute("name"); my $temp2=$address->getAttribute("id"); print("$temp1\t$temp2\n\n"); } } } open(INFILE,">C:/perl/perl_tests/xmlin2.xml"); $doc->printToFile("C:/perl/perl_tests/xmlin2.xml"); $doc->dispose; close(INFILE);

        Hi ankit.tayal560,

        You don't need the open and close - printToFile does all the handling of writing to the file for you.

        As for the error message, it appears you've come across a bug - or at least a deficiency in the documentation - of XML::DOM. The document needs to have an "XMLDecl" set. You can do this for example via: $doc->setXMLDecl($doc->createXMLDecl('1.0','UTF-8'));

        Hope this helps,
        -- Hauke D

Re: How to modify an XML file using XML::DOM
by choroba (Cardinal) on Sep 28, 2016 at 08:52 UTC
    Just a note: much easier in xsh, a wrapper around XML::LibXML :
    open xmlin.xml ; for /config/server/address[@name="tayal" and @id=70889] { set @name "Joey" ; set @id 67890 ; } save :b ;

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: How to modify an XML file using XML::DOM
by Laurent_R (Canon) on Sep 28, 2016 at 06:12 UTC
    You can't modify a sequential file like that. You are amending a copy of the file in memory, then you need to write back your modified content back to a file, either to a new copy of the original file or, if you are sure of what you're doing, back to the original file.

      yes I got that point. tried this but gives me an error : can't call method "getEncoding" on an undefined value...

      use strict; use warnings; use Data::Dumper; use XML::DOM; my $parser=new XML::DOM::Parser; my $doc=$parser->parsefile('C:\perl\perl_tests\xmlin.xml') or die$!; my $root=$doc->getDocumentElement(); my @address=$root->getElementsByTagName("address"); foreach my $address(@address) { if($address->getAttribute("name") eq "tayal") { if($address->getAttribute("id")=='70889') { $address->setAttribute("name","Joey"); $address->setAttribute("id","67890"); my $temp1=$address->getAttribute("name"); my $temp2=$address->getAttribute("id"); print("$temp1\t$temp2\n\n"); } } } open(INFILE,">C:/perl/perl_tests/xmlin2.xml"); $doc->printToFile("C:/perl/perl_tests/xmlin2.xml"); $doc->dispose; close(INFILE);
      .