Scripting question, replacement in xml file

Hi Anybody can help me to make a script that replace string "Su saldo es" with "Your balance" in XML block if it start with Text Id=98 and Text Id= 12 only sample of part of file below

<Text Id="98">
 <Language id="1">Su saldo es $mainAccountBalance1Tiene ademas $dedicatedAccount1Balance1 mensajes de texto</Language>
 <Language id="2"></Language>
 <Language id="3">Su saldo es $mainAccountBalance1Tiene ademas $dedicatedAccount1Balance1 mensajes de texto</Language>
 <Language id="4">Su saldo es $mainAccountBalance1Tiene ademas $dedicatedAccount1Balance1 mensajes de texto</Language>
 </Text>
 <Text Id="96"> 
<Language id="1">Su saldo es $mainAccountBalance1.</Language>
 <Language id="2">Su saldo es $mainAccountBalance1.</Language>
 </Text>
 <Text Id="12"> 
<Language id="1">Su saldo es $mainAccountBalance1.</Language>
 <Language id="2">Your balance  $mainAccountBalance1.</Language> 
</Text>

Do not hijack threads of other people - open up your own.
Do use code tags when posting code, data or logs etc.
Do use meaningful subjects, not just "help me...".

Thanks.

1 Like

Hi Ashu_099,

1.- Replace? with what?
2.- That xml file is not well formed.
3.- Show sample output to get more helpful answers.

1 Like

Replace with let say "XYZ" but condition is that XML block should begin with particulare Text Id ..

---------- Post updated at 10:48 AM ---------- Previous update was at 10:28 AM ----------

A solution to your problem using perl and the module XML::Twig:

$ cat infile
<root>
<Text Id="98">
        <Language id="1">Su saldo es $mainAccountBalance1Tiene ademas $dedicatedAccount1Balance1 mensajes de texto</Language>
        <Language id="2"></Language> 
        <Language id="3">Su saldo es $mainAccountBalance1Tiene ademas $dedicatedAccount1Balance1 mensajes de texto</Language> 
        <Language id="4">Su saldo es $mainAccountBalance1Tiene ademas $dedicatedAccount1Balance1 mensajes de texto</Language> 
</Text>  
<Text Id="96"> 
        <Language id="1">Su saldo es $mainAccountBalance1.</Language> 
        <Language id="2">Su saldo es $mainAccountBalance1.</Language> 
</Text>  
<Text Id="12"> 
        <Language id="1">Su saldo es $mainAccountBalance1.</Language> 
        <Language id="2">Your balance  $mainAccountBalance1.</Language> 
</Text>
</root>
$ cat script.pl
#!/usr/bin/perl

use strict;
use warnings;
use XML::Twig;

{
        my $twig = XML::Twig->new(
                twig_handlers => {
                        q{Text[@Id="98"]/Language} => sub {
                                $_->subs_text( qr{(?ix)su \s+ saldo \s+ es \s+ \$mainAccountBalance1Tiene (?=\s)}, 'XYZ' );
                        }
                },
                pretty_print => 'indented',
        )->parsefile( shift )->print;
}
$ perl-5.14.2 script.pl infile
<root>
  <Text Id="98">
    <Language id="1">XYZ ademas $dedicatedAccount1Balance1 mensajes de texto</Language>
    <Language id="2"></Language>
    <Language id="3">XYZ ademas $dedicatedAccount1Balance1 mensajes de texto</Language>
    <Language id="4">XYZ ademas $dedicatedAccount1Balance1 mensajes de texto</Language>
  </Text>
  <Text Id="96">
    <Language id="1">Su saldo es $mainAccountBalance1.</Language>
    <Language id="2">Su saldo es $mainAccountBalance1.</Language>
  </Text>
  <Text Id="12">
    <Language id="1">Su saldo es $mainAccountBalance1.</Language>
    <Language id="2">Your balance  $mainAccountBalance1.</Language>
  </Text>
</root>
1 Like

Thanks for Quick Response,Can you modify the perl script so that the output look like this

<root>
 <Text Id="98">         
<Language id="1">Your Balance $mainAccountBalance1Tiene ademas $dedicatedAccount1Balance1 mensajes de texto</Language>         
<Language id="2"></Language>
 <Language id="3">Your Balance $mainAccountBalance1Tiene ademas $dedicatedAccount1Balance1 mensajes de texto</Language>
 <Language id="4">Your Balance $mainAccountBalance1Tiene ademas $dedicatedAccount1Balance1 mensajes de texto</Language>
 </Text> 
  <Text Id="96">
 <Language id="1">Su saldo es $mainAccountBalance1.</Language>
 <Language id="2">Su saldo es $mainAccountBalance1.</Language>  
</Text> 
  <Text Id="12"> 
         <Language id="1">Your Balance $mainAccountBalance1.</Language>
 <Language id="2">Your balance  $mainAccountBalance1.</Language> 
 </Text> </root>

I don't know why you changed the text of the bottom. It's not inside <Text Id="98">. Give a try to:

$ cat script.pl                                                                                                                                                                                                                              
#!/usr/bin/perl                                                                                                                                                                                                                              
                                                                                                                                                                                                                                             
use strict;                                                                                                                                                                                                                                  
use warnings;                                                                                                                                                                                                                                
use XML::Twig;                                                                                                                                                                                                                               
                                                                                                                                                                                                                                             
{                                                                                                                                                                                                                                            
        my $twig = XML::Twig->new(                                                                                                                                                                                                           
                twig_handlers => {                                                                                                                                                                                                           
                        q{Text[@Id="98"]/Language} => sub {                                                                                                                                                                                  
                                $_->subs_text( qr{(?ix)su \s+ saldo \s+ es (?=\s)}, 'Your Balance' );                                                                                                                                        
                        }                                                                                                                                                                                                                    
                },                                                                                                                                                                                                                           
                pretty_print => 'indented',                                                                                                                                                                                                  
        )->parsefile( shift )->print;                                                                                                                                                                                                        
}                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
$ perl-5.14.2 script.pl infile                                                                                                                                                                                                          
<root>                                                                                                                                                                                                                                       
  <Text Id="98">                                                                                                                                                                                                                             
    <Language id="1">Your Balance $mainAccountBalance1Tiene ademas $dedicatedAccount1Balance1 mensajes de texto</Language>                                                                                                                   
    <Language id="2"></Language>                                                                                                                                                                                                             
    <Language id="3">Your Balance $mainAccountBalance1Tiene ademas $dedicatedAccount1Balance1 mensajes de texto</Language>                                                                                                                   
    <Language id="4">Your Balance $mainAccountBalance1Tiene ademas $dedicatedAccount1Balance1 mensajes de texto</Language>                                                                                                                   
  </Text>                                                                                                                                                                                                                                    
  <Text Id="96">                                                                                                                                                                                                                             
    <Language id="1">Su saldo es $mainAccountBalance1.</Language>                                                                                                                                                                            
    <Language id="2">Su saldo es $mainAccountBalance1.</Language>                                                                                                                                                                            
  </Text>                                                                                                                                                                                                                                    
  <Text Id="12">                                                                                                                                                                                                                             
    <Language id="1">Su saldo es $mainAccountBalance1.</Language>                                                                                                                                                                            
    <Language id="2">Your balance  $mainAccountBalance1.</Language>
  </Text>
</root>

Hi Birei,

Well,
I have long XML file and i want to replace XML twig that start with Text Id=98,12 and many more ..

Is it possible to give the input from external file.

In Perl code you mentioned only one Id=98 ( @id="98" )

q{Text[@Id="98"]/Language}
I want to add more Id and i want to give list of Id from external file from where its read example

cat Text Id_file
98
12
10
55
..
..
..

Try following solution. Now the script accepts two arguments. The first one is a file with a number per line, and the second one is the xml file:

$ cat infile
98
12
$ cat script.pl
#!/usr/bin/perl

use strict;
use warnings;
use XML::Twig;

my (%id);

die qq|Usage: perl $0 <file-with-ids> <xml-file>\n| unless @ARGV == 2;

{
        open my $fh, '<', shift or die qq|ERROR: $!\n|;
        while ( my $line = <$fh> ) {
                chomp $line;
                $id{ $line } = 1;
        }
}

{
        my $twig = XML::Twig->new(
                twig_handlers => {
                        q{Text[@Id]} => sub {
                                return unless exists $id{ $_->att( 'Id' ) };
                                for my $c ( $_->children( 'Language' ) ) {
                                        $c->subs_text( qr{(?ix)su \s+ saldo \s+ es (?=\s)}, 'Your Balance' );
                                }
                        }
                },
                pretty_print => 'indented',
        )->parsefile( shift )->print;
}

$ perl-5.14.2 script.pl infile xmlfile 
<root>
  <Text Id="98">
    <Language id="1">Your Balance $mainAccountBalance1Tiene ademas $dedicatedAccount1Balance1 mensajes de texto</Language>
    <Language id="2"></Language>
    <Language id="3">Your Balance $mainAccountBalance1Tiene ademas $dedicatedAccount1Balance1 mensajes de texto</Language>
    <Language id="4">Your Balance $mainAccountBalance1Tiene ademas $dedicatedAccount1Balance1 mensajes de texto</Language>
  </Text>
  <Text Id="96">
    <Language id="1">Su saldo es $mainAccountBalance1.</Language>
    <Language id="2">Su saldo es $mainAccountBalance1.</Language>
  </Text>
  <Text Id="12">
    <Language id="1">Your Balance $mainAccountBalance1.</Language>
    <Language id="2">Your balance  $mainAccountBalance1.</Language>
  </Text>
</root>
1 Like

Hi ,
I tried to run the script but my server don`t have XML twig perl module.
And i am not able to install the XML parser or Twig module.

Is there any other way to achieve same result without using Twig.

Yes. There are many ways but the easiest one is to use a XML parser. I don't know the available tools of your server so it's your decission. But take into account that process XML data with sed or awk usually is a hard work and prone to errors. I don't use them for this kind of task.

can you suggest something using Awk ..i appreciate

Are you kidding me?

I've done three diferent versions of a script to solve your problem althought your specifications were not clear since the first post. I did some effort to help you, and now you tell me that couldn't execute any of them. Why didn't you tell me that couldn't run that program, or that perl is not an option, or at least that you can't use an external module, or that you are looking for an awk solution, or whatever?

Here there is people with amazing awk skills, not me. I'm sure that one of them too will help you.

Never Mind..thanks for your support.