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

Hi, I am creatin a project that opens an XML file using xml:simple, removes an element from it, and then saves it and closes. So far I have managed to get it to read the XML in, and it appears to save it, but with no update. Here is what I have. The $dat variable is an integer number referring to which 'page' element is to be removed.
# create object my $xml = new XML::Simple(forcearray => 1); # read XML file my $data = $xml->XMLin("../services/xml/".$docid.".xml"); my $pageobj=$data->{page}; delete $data->{page}[$dat]; my $xmlO = $xml->XMLout($data); open FILE, ">../services/xml/".$docid.".xml" or die; print FILE $xmlO; close FILE;
Many thanks in advance, and I look forward to many years at the monastery, I am really enjoying getting into Perl

Replies are listed 'Best First'.
Re: array/hash question with XML simple
by VinsWorldcom (Prior) on Mar 13, 2009 at 13:43 UTC

    Are you sure your $dat variable contains a number that corresponds to a valid array index for PAGE in the XML file?

    Your code works for me:

    use strict; use XML::Simple; my $docid = "pounces"; my $dat = $ARGV[0];

    Used 2 files, both containing the same data so I could diff between runs. Both files had this content:

    <opt version="1.0"> <page ui="gtk-gaim"> <account protocol="prpl">VinsWorldcom1</account> <actions> <action type="popup-notify" /> </actions> </page> <page ui="gtk-gaim"> <account protocol="prpl">VinsWorldcom2</account> <actions> <action type="popup-notify" /> </actions> </page> </opt>

    Run on Windows ActiveState Perl v5.8.8:

    {C} > 750398.pl 2 {C} > diff pounces.xml "Copy of pounces.xml" {C} > 750398.pl 1 {C} > diff pounces.xml "Copy of pounces.xml" 7a8,13 > <page ui="gtk-gaim"> > <account protocol="prpl">VinsWorldcom2</account> > <actions> > <action type="popup-notify" /> > </actions> > </page>

    So you can see in the first run when I ask to delete "PAGE - 2" from the "2" as ARGV, nothing changes because there are only 2 PAGE array elements ([0] and 1). When I run it again as ask for 1, the second entry appears in the "COPY OF" file (as nothing happens to that file, it's my baseline), but it's deleted from the 'pounces.xml' file.

      Many thanks for your help, Indeed $dat did contain the number. It now works as I wanted. What I believe was going wrong was that I was also calling the print command in various places, and with these print commands in place, it seems to stop working.
      my $pageobj=$data->{page}; print @$pageobj; delete $data->{page}[$dat]; print @$pageobj; my $xmlO = $xml->XMLout($data); open FILE, ">../services/xml/".$docid.".xml" or die; print FILE $xmlO; close FILE;
      This code does not work, but with the prints removed it does, so does calling print actually change the structure of the data structure? if so that would be good to know. Many thanks for your help, it working on yours meant I could focus my efforts away from thinking my syntax was wrong, and helped me find the real problem.
Re: array/hash question with XML simple
by weismat (Friar) on Mar 13, 2009 at 13:43 UTC
    I think you need to use splice instead of delete to modify the array. splice @{$data->{page}} $dat 1 should do what you want (untested).
      Thanks for this, I had not ever used the splice method, but after now reading about it, it does indeed sound useful. Many thanks for your help