
Changing XML Tag Value in Perl
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;
}
--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Re: Changing XML Tag Value in Perl
Since the structure of the XML output is not so complicated and
massive, you might want to try with the Perl Module "XML::Smart":
http://search.cpan.org/~gmpassos/XML-Smart-1.6.9/lib/XML/Sma rt.pm
On 4/11/11, Rajpreet <rajpreetsidhu [at] gmail.com> wrote:
> 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;
> }
>
>
>
> --
> To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
> For additional commands, e-mail: beginners-help [at] perl.org
> http://learn.perl.org/
>
>
>
--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Re: Changing XML Tag Value in Perl
On 11/04/2011 19:10, Rajpreet wrote:
>
> 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.
This is a design issue. There is a specification mismatch and someone
has made a decision to make things even worse.
If your source is XML and bound to stay that way then the proper way to
do things is to apply an XSLT transform to all <FINANCE GROUP> elements.
You cannot do this properly in Perl because you cannot predict the
contents of the element you are required to transform, and copying it
verbatim is unlikely to succeed.
IMO your senior needs a slap. Just make sure that, if you write a simple
global
s/<(\/?)FINANCE_GROUP>/<$1FINANCIAL_SYSTEMS>/g
you expect it to go wrong. That is not XML.
Rob
--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Re: Changing XML Tag Value in Perl
On 12/04/2011 17:22, Carlos Ivan Sosa wrote:
>
> Since the structure of the XML output is not so complicated and
> massive
Carlos this is data. Data grows.
Rob
--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Re: Changing XML Tag Value in Perl
On 4/12/11, Rob Dixon <rob.dixon [at] gmx.com> wrote:
> On 12/04/2011 17:22, Carlos Ivan Sosa wrote:
>>
>> Since the structure of the XML output is not so complicated and
>> massive
>
> Carlos this is data. Data grows.
>
Ohh sorry, misread.
> Rob
>
--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Re: Changing XML Tag Value in Perl
On 13/04/2011 01:42, Carlos Ivan Sosa wrote:
> On 4/12/11, Rob Dixon<rob.dixon [at] gmx.com> wrote:
>> On 12/04/2011 17:22, Carlos Ivan Sosa wrote:
>>>
>>> Since the structure of the XML output is not so complicated and
>>> massive
>>
>> Carlos this is data. Data grows.
>>
>
> Ohh sorry, misread.
No I don't think so. You recommended XML::Smart, and your post was a
very sound one. I was trying to make the point that it is dangerous to
make any assumptions about the nature of the data that a program has to
handle.
I have no experience of the module (but I am installing it as I type!)
and cannot comment on its worthiness, but thank you for the pointer.
Rob
--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Re: Changing XML Tag Value in Perl
Thanks for your replies. But the above message is jst a sample and the
exact message we get is pretty huge(its a trading sysem message)... I
do have XML Parser installed.. I was trying to format a sample message
using start and a default handler. I do get data in a variable and can
change it, but how do I get the changed XML message in a new file. My
question might be confusing or silly, but thats where I am currently
stuck . I just wrote a dummy script-
#!/usr/bin/perl
use XML::Parser;
use Data::Dumper ;
open(XML, "a.txt") || die("Could not open file XML_FILE !"); ###
handler
my $Data = <XML>;
close(XML);
&ReplaceXMLValue($Data,'MOSP_Trader_Code','1111111111111');
sub ReplaceXMLValue
{
my $Data = shift [at] _;
my $tagName = shift [at] _;
my $NewValue = shift [at] _;
my $parser = new XML::Parser ( Handlers => { # Creates our
parser object
Start => \&hdl_start,
Default => \&hdl_default,
});
$parser->parse($Data);
print " \n\n\n Formatted data is - $Data \n\n\n";
}
# The Handlers
sub hdl_start{
my ($p, $elt, %atts) = [at] _;
return unless $elt eq 'MOSP_Trader_Code'; # We're only
interrested in what's said
$flag=1;
}
sub hdl_default {
my ($p, $data) = [at] _;
if ($flag == 1)
{
print "Inside default handler \n";
if ($data eq 'CHL')
{
print "chaging data value form CHL to POST\n";
$data ='POST';
print "$data\n";
$flag =0;
}
}
} # End of default_handler
--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Re: Changing XML Tag Value in Perl
From: Rajpreet <rajpreetsidhu [at] gmail.com>
> Thanks for your replies. But the above message is jst a sample and the
> exact message we get is pretty huge(its a trading sysem message)... I
> do have XML Parser installed.. I was trying to format a sample message
> using start and a default handler. I do get data in a variable and can
> change it, but how do I get the changed XML message in a new file. My
> question might be confusing or silly, but thats where I am currently
> stuck . I just wrote a dummy script-
>
> #!/usr/bin/perl
> use XML::Parser;
> ....
Using XML::Parser directly is very seldom the right thing to do.
Especially if you are just starting with Perl.
See for example the filter mode of XML::Rules or have a look at
XML::Twig. Both can handle huge XMLs without any problem. If used
well. See the examples!
Jenda
===== Jenda [at] Krynicky.cz === http://Jenda.Krynicky.cz =====
When it comes to wine, women and song, wizards are allowed
to get drunk and croon as much as they like.
-- Terry Pratchett in Sourcery
--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Re: Changing XML Tag Value in Perl
On Apr 19, 7:56=A0am, Je... [at] Krynicky.cz ("Jenda Krynicky") wrote:
> From: =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Rajpreet <rajpreetsi... [at] gmail.c=
om>
>
> > Thanks for your replies. But the above message is jst a sample and the
> > exact message we get is pretty huge(its a trading sysem message)... I
> > do have XML Parser installed.. I was trying to format a sample message
> > using start and a default handler. I do get data in a variable and can
> > change it, but how do I get the changed XML message in a new file. My
> > question might be confusing or silly, but thats where I am currently
> > stuck . I just wrote a dummy script-
>
> > #!/usr/bin/perl
> > use XML::Parser;
> > ....
>
> Using XML::Parser directly is very seldom the right thing to do.
> Especially if you are just starting with Perl.
>
> See for example the filter mode of XML::Rules or have a look at
> XML::Twig. Both can handle huge XMLs without any problem. If used
> well. See the examples!
>
> Jenda
> =3D=3D=3D=3D=3D Je... [at] Krynicky.cz =3D=3D=3Dhttp://Jenda.Krynicky.cz=3D=3D=
=3D=3D=3D
> When it comes to wine, women and song, wizards are allowed
> to get drunk and croon as much as they like.
> =A0 =A0 =A0 =A0 -- Terry Pratchett in Sourcery
Thanks for the response. Appreciated.
--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Re: Changing XML Tag Value in Perl
On 18/04/2011 21:55, Rajpreet wrote:
> Thanks for your replies. But the above message is jst a sample and the
> exact message we get is pretty huge(its a trading sysem message)... I
> do have XML Parser installed.. I was trying to format a sample message
> using start and a default handler. I do get data in a variable and can
> change it, but how do I get the changed XML message in a new file. My
> question might be confusing or silly, but thats where I am currently
> stuck . I just wrote a dummy script-
>
> #!/usr/bin/perl
> use XML::Parser;
> use Data::Dumper ;
> open(XML, "a.txt") || die("Could not open file XML_FILE !"); ### handler
> my $Data =<XML>;
> close(XML);
> &ReplaceXMLValue($Data,'MOSP_Trader_Code','1111111111111');
> sub ReplaceXMLValue
> {
> my $Data = shift [at] _;
> my $tagName = shift [at] _;
> my $NewValue = shift [at] _;
> my $parser = new XML::Parser ( Handlers => { # Creates our parser object
> Start => \&hdl_start,
> Default => \&hdl_default,
> });
> $parser->parse($Data);
>
> print " \n\n\n Formatted data is - $Data \n\n\n";
> }
> # The Handlers
> sub hdl_start{
> my ($p, $elt, %atts) = [at] _;
>
> return unless $elt eq 'MOSP_Trader_Code'; # We're only interrested in what's said
> $flag=1;
> }
> sub hdl_default {
> my ($p, $data) = [at] _;
> if ($flag == 1)
> {
>
> print "Inside default handler \n";
> if ($data eq 'CHL')
> {
> print "chaging data value form CHL to POST\n";
> $data ='POST';
> print "$data\n";
> $flag =0;
> }
> }
> } # End of default_handler
There is a 'Style' option to XML::Parser which, if set to 'Stream', will
cause the symbols in the parsed XML to be normalised and printed to
STDOUT. If appropriately-named subroutines exist, then instead of
sending the symbol to output, the subroutine will be called with the
value in $_.
If there is a procedure called Text(), it will be called each time a
text item in the XML is encountered, and so it could examine the context
and the content of $_ and modify it if necessary before calling print.
The program below uses this technique to perform the transformation that
you have described. Note that the XML::Expat object is passed to Text()
as the first (and only) parameter, and can be used to establish the name
of the current element.
HTH,
Rob
use strict;
use warnings;
use XML::Parser;
ReplaceXMLValue(*DATA, 'MOSP_Trader_Code', 'CHL', 'POST');
sub ReplaceXMLValue {
no warnings 'closure';
my ($fh, $tag_name, $old_value, $new_value) = [at] _;
my $parser = new XML::Parser(Style => 'Stream');
sub Text {
my $expat = shift;
if ($expat->current_element eq $tag_name) {
s/\A(\s*)\Q$old_value\E(\s*)\z/$1$new_value$2/;
}
print;
};
$parser->parse($fh);
}
__DATA__
<myxml>
<dataset id="1">
<field1>
Field 1 Data
</field1>
<field2>
Field 2 Data
</field2>
<MOSP_Trader_Code>CHL</MOSP_Trader_Code>
<field3>
Data associated with field 3
</field3>
<field4>
Data for field 4
</field4>
</dataset>
</myxml>
**OUTPUT**
<myxml>
<dataset id="1">
<field1>
Field 1 Data
</field1>
<field2>
Field 2 Data
</field2>
<MOSP_Trader_Code>POST</MOSP_Trader_Code>
<field3>
Data associated with field 3
</field3>
<field4>
Data for field 4
</field4>
</dataset>
</myxml>
--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/