for example, lets say the test on server02 failed, what procedure
would need to occur to change the xml file as follows? If possible I
would prefer to do this via traditional xml methods and not text file
parsing. I'm just a little lost as to how to do it...
<app name="hokiepokie">
<instance host="server01" port="8080" Off="0"/>
<instance host="server02" port="8081" Off="1"/>
<instance host="server03" port="8082" Off="0"/>
</app>
Here is one approach. This avoids regenerating the entire xml file
from scratch. The raw xml is kept intact. Only the lines you pick and
modify are changed.
The capture buffers are just array's of sequence number which point to a
central data repository. The Dump function uses the sequence number
to display the raw data. Modifications are made using the sequence reference.
This will be released soon.
sln
===========================================================
<<XML;
<!--
Notes: This xml file contains server/port information.
-->
<root>
....
....
<app name="hokiepokie">
<instance host="server01" port="8080" Off="0"/>
<instance host="server02" port="8081" Off="0"/>
<instance host="server03" port="8082" Off="0"/>
</app>
....
....
</root>
XML
# Your program.pl
# ------------
use strict;
use warnings;
use RXParse; # VERSIN 2
my $p = new RXParse();
sub starth
{
my ($obj, $el, $term, @attr) = @_;
my $buffer = lc($el);
if ($buffer eq 'instance')
{
$obj->CaptureOn ( $buffer);
}
}
sub endh
{
my ($obj, $el, $term) = @_;
my $buffer = lc($el);
if ($buffer eq 'instance')
{
$obj->CaptureOff ( $buffer, 1);
}
}
$p->setMode( 'resume_onerror'=> 1 );
$p->setHandlers ( 'start' => \&starth, 'end' => \&endh);
my $fname = 'c:\temp\hokie.xml';
open my $fh, $fname or die "can't open $fname ...";
$p->CaptureOn ( 'ALL');
my $parse_errors = $p->parse ( $fh);
$p->CaptureOff ( 'ALL');
print STDERR "Parse errors = $parse_errors\n";
close $fh;
$p->DumpCaptureBuffs (); # to view buffers
## Process the 'instance' buffer raw data. Can use rxparse built-ins if needed.
## There are many ways to do this, this is just one.
## ...
## Xml-Simple example, straight forward but not tested
#
if (0)
{
use XML::Simple;
## Get 'instance' buffer ref's to its raw data
my @instrefs = $p->GetCaptureBuffer ( 'instance'); # this function is not firm yet
## Process it
foreach my $iref (@instrefs)
{
if (defined $$iref) # In this case it will always be defined
{
my $simpref = XMLin ( $$iref, SuppressEmpty => '');
my ($host, $port, $off) = ($simpref->{host}, $simpref->{port}, $simpref->{off});
## Check the host/port status for on/off
if (1) {
$simpref->{off} = 1; # Turn it off
} else {
$simpref->{off} = 0; # Turn it on (or skip if on by default)
}
## Write it back to the instance buffer (if 'off' modified)
$$iref = XMLout ( $simpref);
}
}
## All done, write the 'all' buffer out to a file (if 'off' modified)
if (1)
{
my $fname = 'c:\temp\hokie_new.xml';
open my $fh, $fname or die "can't open $fname ...";
$p->WriteCaptureBuffer ( 'all', $fh); # this function is not firm yet.
close $fh; # can pass in file handle or ref to recieving buf.
}
}
__END__
BUFFER: instance
=====================================
index seqence
----- --------
[0] 2 <instance host="server01" port="8080" Off="0"/>
[1] 4 <instance host="server02" port="8081" Off="0"/>
[2] 6 <instance host="server03" port="8082" Off="0"/>
BUFFER: all
=====================================
index seqence
----- --------
[0] 1 <!--
Notes: The file contains server/port information.
-->
<root>
....
....
<app name="hokiepokie">
[1] -2
[2] 3
[3] -4
[4] 5
[5] -6
[6] 7
</app>
....
....
</root>