package Utils::XMLUtils; use strict; use XML::DOM; use XML::DOM::Xpath; use XML::Writer; require Exporter; use vars qw(@ISA @EXPORT_OK $VERSION); @ISA = ('Exporter'); @EXPORT_OK = qw(loadXMLFile checkIfExists getParentNode getValueFromPath getNodesFromPath getValuesFromPath getNodeValue getNodeWithValue createNewElement createTextElement assignChild getNodeFromPath createXMLDocument cloneNode replaceNode getChildren getXMLNodes wrtiteTofile getNodeName ); # This function checks the existence of a given path under a specified node. # @param $node Node in the XML tree from where the search should start. # @param $npath Path to be searched for existance. Follows XPath format. sub checkIfExists { my ($node, $nPath) = @_; my $bStatus; $bStatus = $node->exists($nPath); return $bStatus; } # This function retrieves the parent node of the specified node. # # @param $node Node in the XML tree. sub getParentNode { my ($node) = @_; my $pNode = $node->getParentNode; return $pNode; } # This function retrieves text value from the given path under a specified node. # If the path matches to multiple nodes then the text value from the # first node will be retrieved. # # @param $node Node in the XML tree from where the search should start. # @param $npath Path to be used to retrieve the text value. # Follows XPath format. sub getValueFromPath { my ($node, $nPath) = @_; my $strValue = ""; my @nodes = $node->findnodes($nPath); my $length = @nodes; if ($length > 0) { my @chlds = $nodes[0]->getChildNodes; foreach my $tNode (@chlds) { if ($tNode->getNodeTypeName eq "TEXT_NODE") { $strValue = $tNode->getNodeValue; last; } } } return $strValue; } # This function retrieves all the node references matching to the given path # under a specified node. # # @param $node Node in the XML tree from where the search should start. # @param $npath Path to be used to retrieve the nodes. Follows XPath format. sub getNodesFromPath { my ($node, $nPath) = @_; my @nodes = $node->findnodes($nPath); return @nodes; } # This function returns the first node references matching to the given path # under a specified node. # # @param $node Node in the XML tree from where the search should start. # @param $npath Path to be used to retrieve the nodes. Follows XPath format. sub getNodeFromPath { my ($node, $nPath) = @_; my @nodes = $node->findnodes($nPath); return $#nodes >= 0 ? $nodes[0] : undef; } # This function retrieves text values from all the nodes matching to the given # path under a specified node. # # @param $node Node in the XML tree from where the search should start. # @param $npath Path to be used to retrieve the text values. # Follows XPath format. sub getValuesFromPath { my ($node, $nPath) = @_; my $strValue = ""; my @values; my @nodes = $node->findnodes($nPath); my $length = @nodes; foreach my $mNode (@nodes) { my @chlds = $mNode->getChildNodes; foreach my $tNode (@chlds) { if ($tNode->getNodeTypeName eq "TEXT_NODE") { push (@values, $tNode->getNodeValue); last; } } } return @values; } # This function retrieves the text value under a specified node. # # @param $node Node in the XML tree. sub getNodeValue { my ($node) = @_; my $strValue = ""; my @chlds = $node->getChildNodes; foreach my $tNode (@chlds) { if ($tNode->getNodeTypeName eq "TEXT_NODE") { $strValue = $tNode->getNodeValue; last; } } return $strValue; } # This function retrieves the node reference whose text matches to # the specified text. # # @param $node Node in the XML tree from where the search should start. # @param $npath Path to be used to match the text values. # Follows XPath format. # @param $strExpValue Expected text value. sub getNodeWithValue { my ($node, $nPath, $strExpValue) = @_; my $strValue = ""; my $resNode; my $bFound = 0; my @nodes = $node->findnodes($nPath); foreach my $mNode (@nodes) { my @chlds = $mNode->getChildNodes; foreach my $tNode (@chlds) { if ($tNode->getNodeTypeName eq "TEXT_NODE") { $strValue = $tNode->getNodeValue; if ($strValue eq $strExpValue) { $resNode = $mNode; $bFound = 1; } last; } } last if ($bFound); } return $resNode; } # This function loads the specified XML file and returns the XML tree. # # @param $filePath Path to the XML file. sub loadXMLFile { my ($filePath) = @_; my $parser = new XML::DOM::Parser; my $doc = $parser->parsefile ($filePath); return $doc; } # This function creates a new xml element. # # @param $node Node to be used for creating XML element. # @param $strElmtName Name of the element to be created. sub createNewElement { my ($node, $strElmtName) = @_; return $node->createElement($strElmtName); } # This function creates a new text node. # # @param $node Node to be used for creating text node. # @param $strText Text to be added to the node. sub createTextElement { my ($node, $strText) = @_; return $node->createTextNode($strText); } # This function adds a given node to another node. # # @param $parentNode Node to which the child node is to be assigned. # @param $chldNode Node to assigned. sub assignChild { my ($parentNode, $chldNode) = @_; $parentNode->appendChild($chldNode); } sub createXMLDocument { return new XML::DOM::Document; } sub replaceNode { my ($parentNode, $oldChildNode, $newChildNode) = @_; $parentNode->replaceChild($newChildNode, $oldChildNode); } sub cloneNode { my ($node) = @_; return $node->cloneNode(1); } sub getChildren { my ($node) = @_; return $node->getChildNodes; } sub getNodeName { my ($node) = @_; return $node->getNodeName; } sub wrtiteTofile { my ($node, $file, $appendFile) = @_; my $output; if ($appendFile) { $output = new IO::File(">>$file"); } else { $output = new IO::File(">$file"); } my $writer = new XML::Writer(OUTPUT => $output, DATA_MODE=>1,DATA_INDENT => 4); getXMLNodes($node, $writer); $writer->end(); $output->close(); } sub getXMLNodes { my ($node, $writer) = @_; my $name = $node->getNodeName; if (not ($name eq "#text")) { $writer->startTag($name); foreach my $chldNode ($node->getChildNodes) { getXMLNodes($chldNode, $writer); } $writer->endTag($name); } else { my $val = trim($node->getNodeValue); if (not ($val eq "") ){ $writer->characters($val); } } } sub trim($) { my $string = shift; $string =~ s/^\s+//; $string =~ s/\s+$//; return $string; } 1;