Flora
Flora

Reputation: 55

how to add/delete value into for loop xml?

I would like to add/delete value into xml file using XML::Simple. my following code doesn't work for adding/deleting into xml file. please help to suggest how should i add/delete specific value into XML file using XML::Simple. thanks alot for your help :)

  use XML::Simple;
  use Data::Dumper;
  use feature 'say';
  my $data;
foreach my $run (@{XMLin(\*DATA)->{Run}}) {
    $data->{$run->{NAME}}->{$run->{tag}} =
      {map { $_ => 1 } @{$run->{List}->{Fruit}}};
}
my @user_input = qw(
  Basket1:2A:apple:orange:peach:
  Basket2:2B:apple:banana:orange:grapes:
);
foreach my $line (@user_input) {
    chomp $line
      ; # we don't need this in my example, but you do when you read from a file
    my ($name, $Tag, @fruitlist) = split /:/, $line;
    foreach my $fruit_list (@fruitlist) {
        if (exists $data->{$name}->{$Tag}->{$fruit_list}) {
            say "$fruit_list - existing\n";
          delete $data ->{Start}[0]{Run}[0]{List}[0]{Fruit}{$fruit_list};
          say "$fruit_list deleted\n";
          print XMLout($data);
        }
        else {
            say "$fruit_list - no existing\n";
           $data->{Start}->[0]->{Run}->[0]->{List}->[0]->{Fruit}->[2] = $fruit_list;
           say "$fruit_list added\n";
           print XMLout($data);
        }
    }
}
__DATA__
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Start>
        <Run>
                <NAME>Basket1</NAME>
                <tag>2A</tag>
                <List>
                        <Fruit>pineapple</Fruit>
                        <Fruit>grapes</Fruit>
                </List>
        </Run>
        <Run>
                <NAME>Basket2</NAME>
                <tag>2B</tag>
                <List>
                        <Fruit>Apple</Fruit>
                        <Fruit>dragonfruit</Fruit>
                </List>
        </Run>
          <Run>
                <NAME>Basket3</NAME>
                <tag>2C</tag>
                <List>
                        <Fruit>grapes</Fruit>
                        <Fruit>banana</Fruit>
                </List>
        </Run>
</Start>

Upvotes: 1

Views: 90

Answers (1)

Dragos Trif
Dragos Trif

Reputation: 302

XMLin reads in an xml XMLout generates an xml. You need to write the output of XMLout for the file to change.

This code should work:

    use XML::Simple;
use Data::Dumper;
use feature 'say';
use autodie;

my $data = XMLin('./test.xml');

my @user_input = qw(
  Basket1:2A:apple:orange:peach:
  Basket2:2B:apple:banana:orange:grapes:
);

my $new;
foreach my $line (@user_input) {
    chomp $line;
    # we don't need this in my example, but you do when you read from a file
    my ($name, $Tag, @fruitlist) = split /:/, $line;

      foreach my $fruit ( @{$data->{Run}} ) {
        my $list = {};
        %{$list} = map { $_ => 1 } @{ $fruit->{List}->{Fruit} };

        if ( $fruit->{NAME} eq $name && $fruit->{tag} eq $Tag ) {

          my @test = @{ $fruit->{List}->{Fruit} };
          foreach $f ( @fruitlist ) {
            if ( !$list->{$f} ) {
              push @test, $f;
            }
          }
          print "$fruit->{NAME} $fruit->{tag}";
          print Dumper(\@test);
          $fruit->{List}->{Fruit} = \@test;

        }
      }

}
open (my $fh, '>', 'new.xml' );
print $fh XMLout( $data, RootName => "Start" );
close $fh;

Upvotes: 2

Related Questions