1

Perl script using XML parser to read values in text file and replace it in xml file

how to read xml tag and replace value from text file value. if an entry value is null in install.properties then same has to be updated in property.xml and if entry value is null xml it should get updated with text file value

install.properties text file

TYPE = Patch
LOCATION = 
HOST = 127.1.1.1
PORT = 8080

property.xml file before values are replaced

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <entry key="TYPE">Release</entry>
    <!-- tst  -->
    <entry key="LOCATION">c:/release</entry>
    <entry key="HOST">localhost</entry>    
    <entry key="PORT"></entry>    

</properties>

property.xml file after values has been replaced

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <entry key="TYPE">Patch</entry>
    <!-- tst  -->
    <entry key="LOCATION"></entry>
    <entry key="HOST">127.1.1.1</entry>    
    <entry key="PORT">8080</entry>    

</properties>
1
  • I am trying it on Windows 7 64 bit OS and there is some issue with installing XML-XSH2 through ppm or cpan. Please suggest any other solution. Commented Aug 14, 2013 at 11:47

2 Answers 2

6

A solution using XML::XSH2, a wrapper around XML::LibXML.

#!/usr/bin/perl
use warnings;
use strict;

use XML::XSH2;

open my $INS, '<', 'install.properties' or die $!;

while (<$INS>) {
    chomp;
    my ($var, $val) = split / = /;        # / fix StackOverflow syntax highlighting.
    $XML::XSH2::Map::ins->{$var} = $val;
}

xsh << '__XSH__';
open property.xml ;
for /properties/entry {
    set ./text() xsh:lookup('ins', @key) ;
}
save :b ;
__XSH__

The same programme imlemented using only XML::LibXML:

#!/usr/bin/perl
use warnings;
use strict;

use XML::LibXML;

open my $INS, '<', 'install.properties' or die $!;

my %ins;
while (<$INS>) {
    chomp;
    my ($var, $val) = split / = /;  # / fix StackOverflow syntax highlighting.
    $ins{$var} = $val;
}

my $xml = 'XML::LibXML'->load_xml( location => 'property.xml' );
for my $entry( $xml->findnodes('/properties/entry')) {
    my ($text) = $entry->findnodes('text()');
    $text->setData($ins{ $entry->getAttribute('key') });
}
rename 'property.xml', 'property.xml~';
$xml->toFile('property.xml');
Sign up to request clarification or add additional context in comments.

9 Comments

on Windows 7 64 bit having some problem with ppm install failed: Can't find any package that provides XML::XSH2 no luck with CPAN also can you please suggest some other option
Use XML::LibXML would be fine,
what if an entry is not updated? This would remove the value wouldn't it?
@mirod: Yes. You can test whether xsh:lookup returns anything, and you should probably only loop over /properties/entry[@key]. The specification was not detailed enough :-)
yes mirod, if entry is null then same should be updated. your solution works fine, but adds a space before the value in xml file
|
1

Again, with XML::Twig:

#!/usr/bin/perl

use strict;
use warnings;

use autodie qw( open);

use XML::Twig;

my $IN= "install.properties";
my $XML= "properties.xml";

# load the input file into a a hash key => value
open( my $in, '<', $IN);
my %entry= map { chomp; split /\s*=\s*/; } <$in>;


XML::Twig->new( twig_handlers => { entry => \&entry, },
                keep_spaces => 1,
              )
         ->parsefile_inplace( $XML);

 sub entry
  { my( $t, $entry)= @_;
    if( my $val= $entry{$entry->att( 'key')} )
      { $entry->set_text( $val); }
    $t->flush;
  } 

4 Comments

its working fine with all values in install.properties, but if one entry is null then the next entry name is getting updated in xml file
what do you mean by 'one entry is null'? An entry in the install.properties file, or an entry in the XML file?
if an entry in install.properties like LOCATION = has no value then in xml its adding value as HOST in LOCATION entry. I have updated the my question with one more entry in install.properties and xml file
Oh, you need to change the part that reads that file then. It should look like my %entry; while( <$in>) { chomp; my $(k, $v)= split /\s*=\s*/; $entry{$k}= $v if $k; }. You should be able to do this on your own.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.