Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Changing XML Tag value in Perl Script

by Rajpreet1985 (Initiate)
on Apr 11, 2011 at 16:06 UTC ( [id://898730]=perlquestion: print w/replies, xml ) Need Help??

Rajpreet1985 has asked for the wisdom of the Perl Monks concerning the following question:

Greetings, Requirement goes like this. I have perl script reading from a MQ Series queue. This queue has messages in form of XML.For example- 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. Pl note I would prefer doing below way or other wise I have XML Parser installed. Sample of my script -
# Connect to qmgr $qmgr = MQSeries::QueueManager->new ( QueueManager => $hOpts{m}, AutoC +onnect => 0) or die "Unable to instantiate MQSeries::QueueManager object\n" +; $qmgr->Connect() or die("Unable to connect to queue manager\n" . "Com +pCode => " . $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::MQPM +O_SET_ALL_CONTEXT || + MQSeries::MQPMO_FAIL_IF_QUIESCING}); if ($result > 0) { last; } sleep $time_to_wait; }

Replies are listed 'Best First'.
Re: Changing XML Tag value in Perl Script
by GrandFather (Saint) on Apr 11, 2011 at 21:09 UTC

    I can't tell what GetXMLValue does, but generally using a module such as XML::Twig is the smart way to handle XML parsing and manipulation problems. Consider:

    #!/usr/bin/perl use strict; use warnings; use XML::Twig; my $t = XML::Twig->new( twig_roots => {'CLIENT_INFO/FIELD' => \&convert}, twig_print_outside_roots => 1 ); $t->parse(*DATA); sub convert { my ($t, $elt) = @_; my $txt = $elt->text(); $elt->set_text('FINANCIAL SYSTEMS') if $txt =~ /FINANCE GROUP/i; $elt->print (); } __DATA__ <CLIENT_INFO> <LOCATION> New York </LOCATION> <FIELD> FINANCE GROUP </ +FIELD> <NO_OF_WORKERS> 123 </NO_OF_WORKERS> </CLIENT_INFO>

    Prints:

    <CLIENT_INFO> <LOCATION> New York </LOCATION> <FIELD>FINANCIAL SYSTEMS +</FIELD> <NO_OF_WORKERS> 123 </NO_OF_WORKERS> </CLIENT_INFO>
    True laziness is hard work
      Thanks for your inputs. However problem in my case is my production environment has just XML::Parser . I am not allowed to download XML::Twig or any other module. So options are either to directly manipulate or use XML::Parser. I have not done XML parsing anytime earlier . Would appreciate your inputs. Thanks.

        Well, you could spend the time to recreate the parts of XML::Twig that you need for this project, or you could convince "management" that there is a significant gain to be made by making an exception to the "can't use external modules" rule in this case, or see Yes, even you can use CPAN.

        True laziness is hard work
Re: Changing XML Tag value in Perl Script
by sundialsvc4 (Abbot) on Apr 11, 2011 at 20:27 UTC

    For tasks like this, I suggest using an XML manipulation package such as XML::Twig. (Or XML::Simple, although I have learned to prefer to use Twig because very few “simple” things stay that way for long.)

    These packages will enable you to solve the problem swiftly:

    1. Decode the XML statement, getting a handle to that statement.
    2. Using the handle, issue an XPath expression which will (with no complicated code from you...!) search the XML tree for all occurrences of whatever you’re looking for.
    3. Given the list of nodes returned from that XPath-search, use the appropriate methods of those nodes to make the necessary changes ... to those nodes or, as the case may be, to their neighbors.   (The node-references that you get back from your search point to those nodes in the tree.)
    4. Convert the structure back into an output string.   Q.E.D.

    It will surprise you how little code is actually required to accomplish this kind of task ... and to accomplish it quite thoroughly.   Without a doubt, the systems that your app is talking to, are using these same core libraries and techniques, no matter what language(s) they were written in.   Go and do likewise.™

Re: Changing XML Tag value in Perl Script
by choroba (Cardinal) on Apr 12, 2011 at 15:06 UTC
    I often use XML::XSH2 to manipulate XML:
    create '<CLIENT_INFO> <LOCATION> New York </LOCATION> <FIELD> FINANCE +GROUP </FIELD> <NO_OF_WORKERS> 123 </NO_OF_WORKERS> </CLIENT_INFO>' ; set /CLIENT_INFO/FIELD[text()=" FINANCE GROUP "] "FINANCIAL SYSTEM" ;

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://898730]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (3)
As of 2024-04-19 23:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found