Solved

Perl/Shell Script to edit XML Files

Posted on 2008-10-27
6
1,530 Views
Last Modified: 2013-12-26
Hi Experts,
 I would appreciate some perl/shell scripts which I can use to edit an XML file to insert the data which i have in a flat file.

For ex: Here is a sample XML file

<oim-data resource="Siebel Resource Object">

<attribute name="IT Resource Type">SIEBEL IT Resource </attribute>


<child-record table="UD_SIEBEL_R">

 <attribute name="Responsibility">SNI - Broker</attribute>
</child-record>
</oim-data>
In the above code, i would want to edit the tag

<attribute name="Responsibility">SNI - Broker</attribute>

and generate multiple XML Files with the data i have from the flat file, the sample flat file as follows

Flat File:
SNI - Inside Sales Leader/Exec
SNI - Collections Agent/Credit Tech
SNI - Data Steward/Info Admin
SNI - Campaign Administrator
SNI - Sales Team Administrator
SNI - Inside Sales User

and would want to name the resulting XML file to as SNI - Inside Sales Leader/Exec.xml and the output XML should look like

<oim-data resource="Siebel Resource Object">

<attribute name="IT Resource Type">SIEBEL IT Resource </attribute>


<child-record table="UD_SIEBEL_R">

 <attribute name="Responsibility">SNI - Inside Sales Leader/Exec</attribute>
</child-record>
</oim-data>


Thanks in advance
0
Comment
Question by:itsme_asif
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
6 Comments
 
LVL 39

Expert Comment

by:Adam314
ID: 22812922
Note that there are some characters in your new names that cannot be used in a filename, such as /.  And, although allowed, spaces are not usually wanted in a filename.  Here is a script that does what you want, replacing the invalid characters with _ in the filename.
#!/usr/bin/perl
use strict;
use warnings;
 
#NOTE: replace flat.txt with the name of your flat file
open(my $in, "<flat.txt") or die "Flat: $!\n";
my @flat = <$in>;
chomp(@flat);
 
local $/;
#NOTE: replace test1.xml with the name of your original xml
open($in, "<test1.xml") or die "xml: $!\n";
my $xml = <$in>;
close($in);
 
foreach (@flat) {
	next unless /\S/;  #Skip blank lines
	my $name=$_;
	$name =~ s/[^\w]/_/g;
	
	my $newxml=$xml;
	$newxml =~ s/(<attribute name="Responsibility">).*(<\/attribute>)/$1$_$2/;
	open(my $out, ">$name.xml") or die "out: $!\n";
	print $out $newxml;
	close($out);
}

Open in new window

0
 

Author Comment

by:itsme_asif
ID: 22813926
Thanks Adam, works like a charm, As far as the file name , even the lines with '/' are getting replaced by an '_', for ex: SNI Broker is getting replaced as SNI___Broker_ , actually i would like to  supply the file names by a different flat file with no '/', can you please make the change for that.
0
 
LVL 39

Expert Comment

by:Adam314
ID: 22815836
Like I said, spaces are not normally wanted in filenames, so the script removes them.  To allow spaces, change line 19 to this:
    $name =~ s/[^\w ]/_/g;
(notice the added space after w)

If you want to supply filenames:
#NOTE: replace flat.txt with the name of your flat file
open(my $in, "<flat.txt") or die "Flat: $!\n";
my @flat = <$in>;
chomp(@flat);
close($in);
 
#NOTE: replaces names.txt with the name of the file containing filenames
open($in, "<names.txt") or die "Names: $!\n";
my @names=<$in>;
chomp(@names);
close($in);
 
local $/;
#NOTE: replace test1.xml with the name of your original xml
open($in, "<test1.xml") or die "xml: $!\n";
my $xml = <$in>;
close($in);
 
for(my $i=0; $i<=$#flat; $i++) {
    next unless $flat[$i] =~ /\S/;  #Skip blank lines
    
    my $newxml=$xml;
    $newxml =~ s/(<attribute name="Responsibility">).*(<\/attribute>)/$1$_$2/;
    open(my $out, ">$names[$i]") or die "out: $!\n";
    print $out $newxml;
    close($out);
}

Open in new window

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:itsme_asif
ID: 22824068
Hi Adam, I tried your above script but i am getting
Use of uninitialized value $_ in concatenation (.) or string on the line

$newxml =~ s/(<attribute name="Group">).*(<\/attribute>)/$1$_$2/;

Here's my flat.txt (names.txt is also the same,its just a copy of flat.txt)

BIABuinessGroupSEC
BIAFINAdhocUser
BIAFINPayDB
BIAFINPayLtd1DB
BIAFINRecvDB
BIAFINRecvLtd1DB
BIAHRAdhocUser
BIAHRPerformanceDB
BIAHRRetentionDB
BIAHRWorkProfileDB
BIAOperatingUnitSEC
BIAPerfMgmntDB
BIAProfitDB
BIAPurchTransDB
BIARlcMgrLvlSEC
BIASTMAdhocUser
BIASellServicesDB
BIASellerLvlSEC
BIBIPWebServices
#!/usr/bin/perl
use strict;
use warnings;
 
#NOTE: replace flat.txt with the name of your flat file
open(my $in, "<flat.txt") or die "Flat: $!\n";
my @flat = <$in>;
chomp(@flat);
close($in);
 
#NOTE: replaces names.txt with the name of the file containing filenames
open($in, "<names.txt") or die "Names: $!\n";
my @names=<$in>;
chomp(@names);
close($in);
 
local $/;
#NOTE: replace test1.xml with the name of your original xml
open($in, "<test1.xml") or die "xml: $!\n";
my $xml = <$in>;
close($in);
 
for(my $i=0; $i<=$#flat; $i++) {
    next unless $flat[$i] =~ /\S/;  #Skip blank lines
    
    my $newxml=$xml;
    $newxml =~ s/(<attribute name="Group">).*(<\/attribute>)/$1$_$2/;
    open(my $out, ">$names[$i]") or die "out: $!\n";
    print $out $newxml;
    close($out);
}

Open in new window

0
 

Author Comment

by:itsme_asif
ID: 22824081
Btw this is my test1.xml
<oim-data resource="OBIEE Account">
 
<attribute name="Domain">OBIEE</attribute>
 
 
<child-record table="UD_OBEGRC_P">
 
 <attribute name="Group">OTMEXTCUSTOMERREADONLY</attribute>
</child-record>
 
</oim-data>

Open in new window

0
 
LVL 39

Accepted Solution

by:
Adam314 earned 500 total points
ID: 22824811
$newxml =~ s/(<attribute name="Group">).*(<\/attribute>)/$1$flat[$i]$2/;
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Background Still having to process all these year-end "csv" files received from all these sources (including Government entities), sometimes we have the need to examine the contents due to data error, etc... As a "Unix" shop, our only readily …
Checking the Alert Log in AWS RDS Oracle can be a pain through their user interface.  I made a script to download the Alert Log, look for errors, and email me the trace files.  In this article I'll describe what I did and share my script.
Learn several ways to interact with files and get file information from the bash shell. ls lists the contents of a directory: Using the -a flag displays hidden files: Using the -l flag formats the output in a long list: The file command gives us mor…
Six Sigma Control Plans

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question