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

Hi I have some problems when I use the XML search and replace. I have try everything to do it but I can't. I am using xml::simple to replace a value from an XML file.
Here my code
#!C:\PERL\bin\perl.exe use strict; use CGI ':standard'; use XML::Simple; #Variables my $var; my $var1; my $var2; $var = 'kool'; $var1 = 'max'; $var2 = "800.55.01"; print header; my @data = ('C:\Program Files\Apache Group\Apache2\htdocs\legastro +nome\XML\Admin\coffee.xml'); my $xml = XMLin((join'', @data)); foreach my $sub (@{$xml->{'subcategory'}}) { foreach my $product (@{$sub->{'product'}}) { foreach my $prod_id (@{$sub->{'prod_id'}}) { if ($prod_id eq $var2) { $prod_id = '800'; #Testing variables :) print "<html><head></head>"; print "<body>"; print "<p>Test</p>"; print "<p><h1>Done</h1></p>"; print "<br\>"; print "<br><br><a href=\'javascript:window.close();\'> +Close this window </a>"; print "</body></html>"; } else { #Testing variables :) print "<html><head></head>"; print "<body>"; print "<p>Test</p>"; print "<p><h1>Fail!!!</h1></p>"; print "<br\>"; print "<br><br><a href=\'javascript:window.close();\'> +Close this window </a>"; print "</body></html>"; } } } } ===DATA=== <?xml version="1.0" encoding="us-ascii"?> <?xml-stylesheet type="text/xsl" href="Adminproduct.xsl"?> <category name="Coffee"> <heading>150 years of know how at the service of a same strate +gy: Taste</heading> <photo>images/bag_legal.jpg</photo> <comments> <paragraph>Roaster since 1851, Caf&#xE9; Legal has a perfect + knowledge of the green coffee market.</paragraph> <paragraph>A revolution in the packaging arena, Caf&#xE9; Le +gal is at the origin of a major break through on the coffee market.</ +paragraph> </comments> <subcategory name="Prestige"> <comments><paragraph>Prestige is a very traditional French + recipe: a blend of Robusta and Arabica beans. The Robusta is known f +or its strength and the Arabica for its delicate flavour.</paragraph> </comments> <photo>images/prestige.jpg</photo> <product>Coffee <channel>D</channel> <channel>A</channel> <product_id>800.55.01</product_id> <brand>Legal</brand> <description>Legal Prestige</description> <conditionning unit="gr">250</conditionning> <packaging_qty>12</packaging_qty> <recipe>/recipes/coffee1.html</recipe> </product> </subcategory> </category>

----------------------------------------------
I always got the error message "Not an ARRAY reference at C:\Program Files\Apache Group\Apache2\cgi-bin\legas\in .pl line 37." Thanks in advance Maxim

20040928 Janitored by Corion: Put code in readmore tags

Replies are listed 'Best First'.
Re: Help XML Search and replace
by borisz (Canon) on Sep 28, 2004 at 13:26 UTC
    You need to let XML::Simple know that subcategory, product and prod_id are arrays, even if you use them only once. Replace your XMLin line with this one and read about KeyAttr and ForceArray in the XML::Simple pod.
    my $xml = XMLin( (join'', <DATA>), KeyAttr => 1, 'ForceArray' => [qw/ +subcategory product prod_id/]);
    Boris
      Thanks guys!! It really help me. Big Thanks
      What you have gave to me work but I can't change any value. It seems my loops doesn't search the appropriate value. Any ideas?? Thanks
        It would be helpful if you tell us, what you like to modify.
        This little peace of code show your data structure.
        use Data::Dumper; my $d = XMLin( (join'', <DATA>), KeyAttr => 1, 'ForceArray' => [qw/subcategory product prod_id/] ); print Dumper($d);
        Boris
Re: Help XML Search and replace
by zejames (Hermit) on Sep 28, 2004 at 12:34 UTC
    Your input to XMLin is incorrect :

    either use a filename :
    my $file = 'C:\Program Files\Apache Group\Apache2\htdocs\legastronome\ +XML\Admin\coffee.xml'; my $xml = XMLin($file);


    or an string :

    open F, '< C:\Program Files\Apache Group\Apache2\htdocs\legastronome\X +ML\Admin\coffee.xml' or die "Problem"; @data = <F>; my $xml = XMLin(join '', @data);


    --
    zejames

      He's already doing that.

      #!/usr/bin/perl use strict; use warnings; sub XMLin { print "[$_[0]]\n"; } my @data = ('C:\Program Files\Apache Group\Apache2\htdocs\legastronome +\XML\Admin\coffee.xml'); my $xml = XMLin((join'', @data)); __END__ [C:\Program Files\Apache Group\Apache2\htdocs\legastronome\XML\Admin\c +offee.xml]

      His code at that point is indeed confused, but that's not the reason for his problem.

      Makeshifts last the longest.