Parsing
Text Files is always an easy way using perl .As a System Admin there
was a requirement for adding Data Sources using the Perl.
In
Tomcat or Jboss we do have the Context.xml or xx-ds.xml file where we
need to update these or create these for configuring the Data
Sources.
These
Can also be created using Java JMX or any other way but what if we
need to parse xml files using PERL.
Perl
Provides a couple of ways for parsing xml files.This articles tell
you about the XML::Simple and XML::LibXML.
For
this article Purpose we use Tomcat Context.xml file and alos Jboss
xxx-ds.xml files for reading , Writing and Deleting.
XML::Simple
, an easy API to read and write XML. XML::Simple is implemented
as an API layer over the XML::Parser module
Now
I Need to Find out the How Many Of the Resources are available and
are configured in Context.xml file for a Tomcat server.
The
Code that I have used for parsing the context.xml file for the above
requirement is
$EWS_DS_FILE="$EWS_CFG_DIR/$VIRT_TARGET/conf/context.xml";
my
$parser=XML::Simple->new();
my
$doc = $parser->XMLin($EWS_DS_FILE,, ForceArray => qr{Resource}
,
keyAttr=>
{ 'Resource', 'name',KeepRoot => 1 }
);
foreach my $key (keys
(%{$doc->{Resource}})) {
print $key;
print "\n";
}
}
Every
object of the XML::Simple class exposes two methods, XMLin() and
XMLout(). The XMLin() method reads an XML file or string and converts
it to a Perl representation; the XMLout() method does the reverse,
reading a Perl structure and returning it as an XML document instance
The
above XMLin reads the file and stores the result in $doc variable.
ForceArray
: This option should be set to true to force nested elements to be
represented as arrays even when there is only one
I
used “Resource” as Key attribute.
Now
the Result that I Obtained
jdbc/com.sample.app.jon.manPoolTXDS2
jdbc/com.sample.app.jon.manPoolTXDS3
jdbc/com.sample.app.jon.manPoolTXDS1
If
you need to extract values assigned to elements in XML ,we can use
$POOLNAME="jdbc/"
. $POOL_NAME;
$EWS_CFG_DIR=$ENV{JBS_CFGDIR};
$EWS_DS_FILE="$EWS_CFG_DIR/$VIRT_TARGET/conf/context.xml";
my
$parser=XML::Simple->new();
my $doc =
$parser->XMLin($EWS_DS_FILE,, ForceArray => qr{Resource} ,
keyAttr=>
{ 'Resource', 'name',KeepRoot => 1 }
);
foreach my $key
(keys (%{$doc->{Resource}})) {
if($key eq
$POOLNAME) {
print
"Name: $key\n";
print
"URL: $doc->{Resource}->{$key}->{url}\n";
print
"JNDI: $key\n";
print
"Factory: $doc->{Resource}->{$key}->{factory}\n";
print
"Type: $doc->{Resource}->{$key}->{type}\n";
print
"DriverName: $doc->{Resource}->{$key}->{driverClassName}\n";
print
"MaxCapacity: $doc->{Resource}->{$key}->{maxActive}\n";
print
"InitialCapacity: $doc->{Resource}->{$key}->{initialSize}\n";
print "Max
Wait: $doc->{Resource}->{$key}->{maxWait}\n";
print
"Time Between Eviction Run:
$doc->{Resource}->{$key}->{timeBetweenEvictionRunsMillis}\n";
print
"Validation Query:
$doc->{Resource}->{$key}->{validationQuery}\n";
print
"Remove Abondoned:
$doc->{Resource}->{$key}->{removeAbandoned}\n";
print
"Test While Idle: $doc->{Resource}->{$key}->{testWhileIdle}\n";
print
"UserID: $doc->{Resource}->{$key}->{username}\n";
print
"PasswordEncrypted: $doc->{Resource}->{$key}->{password}\n";
}
}
}
Now
iam passing the Server name and Pool Name .When I run the Code I get
the results as
Name:
jdbc/com.sample.app.jon.manPoolTXDS1
URL:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
JNDI:
jdbc/com.sample.app.jon.manPoolTXDS1
Factory:
Type:
javax.sql.DataSource
DriverName:
oracle.jdbc.OracleDriver
MaxCapacity:
1
InitialCapacity:
5
Max
Wait: 100
Time
Between Eviction Run: 300000
Validation
Query: SELECT * FROM DUAL
Remove
Abondoned: true
Test
While Idle: true
UserID:
xxxxx
PasswordEncrypted:
xxxxx
I
can get any details I need.
XML::LibXML
:
XML::LibXML provides a standard W3C DOM interface. Documents are
treated as a tree of nodes and the data those nodes contain are
accessed by calling methods on the node objects themselves.
One
of the more exciting features of XML::LibXML is that, in addition to
the DOM interface, it allows you to select nodes using the XPath
language
Iam
have used this for Deleting of Nodes in the Context.xml file.We can
also use this package which can perform the above things as
XML::Simple.
Now
if I want to delete the Few Elements I can use
$EWS_CFG_DIR=$ENV{JBS_CFGDIR};
$EWS_DS_FILE="$EWS_CFG_DIR/$VIRT_TARGET/conf/context.xml";
$DS_NAME="jdbc/".$DS_NAME;
my $parser =
XML::LibXML->new();
my $tree =
$parser->parse_file($EWS_DS_FILE);
my $root =
$tree->getDocumentElement;
my @appPolicies
= $root->getElementsByTagName('Resource');
foreach my
$policy (@appPolicies) {
my
$policy_name = $policy->getAttribute('name');
if($policy_name
eq $DS_NAME) {
$policy->parentNode()->removeChild($policy);
print
"In Equal Policies";
}#Closing
Of If PolicY Nmae
}#Closing of
App Policies
my $changed =
$tree -> toString;
$tree->toFile($EWS_DS_FILE);
DS_NAME
is the Name of the Data Source that I Sent as an Argument for
deleting.
This
is how we can parse Xml files in perl.Iam still working more on these
Packages.I will upload more examples of these.
Happy
learning :-)