Changing XML tag value in Perl

R

Rajpreet

Greetings,

Requirement goes like this. I have perl script reading from a MQ
Series queue. This queue has messages in form of XML.For exmpale
1 message is like -
<CLIENT_INFO>
<LOCATION>
New York
</LOCATION>
<FIELD>
FINANCE GROUP
</FIELD>
<NO_OF_WORKERS>
123
</NO_OF_WORKERS>
<CLIENT_INFO>


My perl script reads messgaes from this queue, and drops them to
another queue after creating a backup in a text file. My requirement
is I have check the value of a particular tag for example, value of
<FIELD>, if that is say "FINANCE GROUP", I have to change it to
"FINANCIAL SYSTEMS" and then drop to the other queue. I tried below,
but for some reason it did not work. COuld you please help.

Sample of my script -


# Connect to qmgr
$qmgr = MQSeries::QueueManager->new ( QueueManager => $hOpts{m},
AutoConnect => 0)
or die "Unable to instantiate MQSeries::QueueManager object
\n";

$qmgr->Connect() or die("Unable to connect to queue manager\n" .
"CompCode => " . $qmgr->CompCode() . "\n" . "Reason => " .
$qmgr->Reason() . " (", MQReasonToText($qmgr->Reason()) . ")\n");

# open input and output queues
my $qIn =MQSeries::Queue->new(QueueManager => $qmgr, Queue =>
$hOpts{i}, Options=>MQSeries::MQOO_INPUT_SHARED )
or die "Unable to open queue $hOpts{i}" ;

my $qOut=MQSeries::Queue->new ( QueueManager => $qmgr, Queue =>
$hOpts{o}, Options=>MQSeries::MQOO_OUTPUT | MQSeries::MQPMO_S
ET_ALL_CONTEXT )
or die "Unable to open queue $hOpts{o}" ;

until( $time_to_die )
{
my $message = MQSeries::Message-
new(MsgDesc=>{Persistence=>1});

# Get message from queue
$result = $qIn->Get( Message => $message, Sync=>1,
Wait=>-1 );
my $msgDescRef = $message->MsgDesc;
my $data = $message->Data;
my $field_name = GetXMLValue($data, "FIELD");
if ($field_name eq 'FINANCE GROUP')
{

$field_name = 'FINANCIAL SYSTEMS';

$msgDescRef->{"FIELD"} = $field_name ;
}
for(1..$num_retries) {
$result = $qOut->Put( Message => $message, Sync => 1,
PutMsgOpts
=>{ Options=>MQSeries::MQPMO_SET_ALL_CONTEXT ||

MQSeries::MQPMO_FAIL_IF_QUIESCING});
if ($result > 0) { last; }

sleep $time_to_wait;
}
 
C

ccc31807

My perl script reads messgaes from this queue, and drops them to
another queue after creating a backup in a text file. My requirement
is I have check the value of a particular tag for example, value of
<FIELD>, if that is  say "FINANCE GROUP", I have to change it to
"FINANCIAL SYSTEMS" and then drop to the other queue.

As a general rule, manipulation of data is much easier if you put it
into some data structure resident in memory. My strategy would be to
read your data into a multi-level hash, using the XML tags as keys,
and then iterate through the hash creating new keys and deleting old
ones as necessary. This is trivial if you have well formed XML, which
you apparently do.

I would recommend that you use XSLT, a tool which is designed for this
purpose. You can write an XSLT script that will do this
transformation. I've never called an XSLT script from a Perl script,
but it ought to be pretty easy.

I don't see any reason to use Perl for this job when a better tool is
available.

CC.
 
R

Rajpreet

Thanks for your inputs. However problem in my case is my production
environment has just XML::parser . I am not allowed to download any
thing. So options are either to directly manipulate or use
XML::parser. I have not done XML parsing anytime earlier . Would
appreciate your inputs. Thanks.
 
X

Xho Jingleheimerschmidt

Rajpreet said:
Thanks for your inputs. However problem in my case is my production
environment has just XML::parser . I am not allowed to download any
thing.

But you are allowed to post to usenet? Do you live in a giant Dilbert
cartoon?
So options are either to directly manipulate or use
XML::parser. I have not done XML parsing anytime earlier . Would
appreciate your inputs. Thanks.

I think XML::Twig is almost exactly what you would need. If you aren't
allowed to use it, you could always look at its source code and see how
it does what it does.

Xho
 
C

ccc31807

Thanks for your inputs. However problem in my case is my production
environment has just XML::parser .

Then I suggest that you ASSUME that all your data is regular, and that
you write a script that uses index(), substr() and friends (not
regular expressions), and write bad input values out to a file.

If your manager doesn't trust you to install a Perl module, he
certainly doesn't trust you to change input values. So just collect
the input errors and send them to him.

You should be able to do what you want easily enough if your XML is
well formed.

might want to do something like this while reading the file:


if ($_ =~ /<FINANCE GROUP>/)
 
C

ccc31807

Sorry for the previous mangles post, I hit the wrong key. See below.

Thanks for your inputs. However problem in my case is my production
environment has just XML::parser .

Then I suggest that you ASSUME that all your data is regular, and that
you write a script that uses index(), substr() and friends (not
regular expressions), and write bad input values out to a file.

If your manager doesn't trust you to install a Perl module, he
certainly doesn't trust you to change input values. So just collect
the input errors and send them to him.

You should be able to do what you want easily enough if your XML is
well formed.

might want to do something like this while reading the file (NOT
TESTED):

while (<DATA>
{
...
if ($_ =~ /<FINANCE GROUP>/)
{
print OUT "<FINANCIAL SYSTEMS>\n";
while (<DATA>)
{
if ($_ =~ m!</FINANCE GROUPS>!)
{
print OUT "</FINANCIAL SYSTEMS>\n";
last;
}
print OUT $_;
}
}
else { print OUT $_; }
...
}

CC
 

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,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top