Parsing an XML file and adding another tag, if the tag is not available / the value is null

P

P

Hi

I have a scenario in which we are adding a new tag to the existing
structure of the XML files, some of the new files created might have
the newly added tag with value / just an empty tag, all I need is to
add the new tag if it is not present with the value available in
another tag, or if it is empty have to give the value from the other
tag to this.
For Example:
Old XML file:
<employee>
<personal_details>
<fname>Annbu</fname>
<lname>P</lname>
<empid>7655</empid>
</personal_details>
......
</employee>

New XML file:
<employee>
<personal_details>
<fname>Annbu</fname>
<lname>P</lname>
<nickname>Annbu</nickname>
<empid>7655</empid>
</personal_details>
......
</employee>

in the new file we have added a new field/tag called <nickname> - for
the existing XML files it has to take the value present in the <fname>
tag, (if the tag is empty we need to add the value, else have to add
the new tag with the value).

Kindly let me know, how to do it with perl, I am new to perl.

thank you.

Regards,
Annbu P
 
J

John Bokma

P said:
Kindly let me know, how to do it with perl, I am new to perl.

Personally I would say use XSLT for stuff like this. But maybe XML::Simple
can solve your problem the Perl way.
 
P

P

Thanks John,

I can't use the XSLT because, we just need to insert the text / the new
tag with the value in the same file, sine there are so many XPATH
expressions in other files that refer to these files.

can you let me know if there is any sample code, that could help me.

Thanks again.

Regards,
Annbu P
 
J

John Bokma

P said:
Thanks John,

I can't use the XSLT because, we just need to insert the text / the
new tag with the value in the same file,

Uhm, you can transform the current one to a new file, and then copy it
over the old one. Doesn't sound impossible to me.
can you let me know if there is any sample code, that could help me.

http://search.cpan.org/~grantm/XML-Simple-2.16/lib/XML/Simple.pm

has examples.

Other option might be:
XML::DOM::Lite
http://search.cpan.org/~rhundt/XML-DOM-Lite-0.15/lib/XML/DOM/Lite.pm


BTW: please don't top post (if you don't know what that means, google for
it).
 
M

mirod

I have a scenario in which we are adding a new tag to the existing
structure of the XML files, some of the new files created might have
the newly added tag with value / just an empty tag, all I need is to
add the new tag if it is not present with the value available in
another tag, or if it is empty have to give the value from the other
tag to this.

Using XML::Twig here is how you would do it:

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

XML::Twig->new( twig_roots => { personal_details => \&add_nick },
twig_print_outside_roots => 1,
keep_spaces => 1,
)
->parsefile( "employee.xml");

sub add_nick
{ my( $t, $details)= @_;
my $fname = $details->first_child( 'fname');
my $nick = $details->first_child( 'nickname');

if( !$nick)
{ $nick = $fname->insert_new_elt( after => nickname =>
$fname->text); }
elsif( $nick->text=~ m{^\s*$})
{ $nick->set_text( $fname->text); }

$t->flush; # output the details and frees the memory
}

A few words of explanation:
twig_roots triggers the associated sub every time a
personal_details element is found,
twig_print_outside_roots prints everything outside of the
personal_details elements
keep_spaces preserves the non-significant spaces in the
input
flush outputs the fragment of the tree
built so far, and frees the memory

OTH
 
T

Tad McClellan

mirod said:
Using XML::Twig here is how you would do it:


[ snip robust code that any sensible person would prefer. ]


Or if the OP is willing to live with a fragile dirty hack, then:

$xml =~ s{(.*<fname>.*?</fname>\n)(.*\n)}
{ $a = $1 . $2;
($b=$1) =~ s/fname/nickname/g;
$a . $b;
}gie;
 
P

P

Thanks Guys, for taking your time out to help me out.

I still have an issue, I can't use XML::Twig, it is not provided with
the version of the UNIX we use here, can you give me some other way
similar to this, with other older packages.

Also this needs to be done for all the XML files in a folder & sub
folders.

Just let me know your thoughts.

Thank you,

Regards,
Annbu P

Tad said:
mirod said:
Using XML::Twig here is how you would do it:


[ snip robust code that any sensible person would prefer. ]


Or if the OP is willing to live with a fragile dirty hack, then:

$xml =~ s{(.*<fname>.*?</fname>\n)(.*\n)}
{ $a = $1 . $2;
($b=$1) =~ s/fname/nickname/g;
$a . $b;
}gie;
 
T

Tad McClellan

P said:
I still have an issue, I can't use XML::Twig, it is not provided with ^^^^^^^^^^^^
the version of the UNIX we use here,


Then install it!


[ snip TOFU, please do not top-post ]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top