NAME
XML::LibXML::Enhanced - adds convenience methods to XML::LibXML and LibXSLT
SYNOPSIS
use XML::LibXML::Enhanced;
my $xml = XML::LibXML::Singleton->instance;
my $xsl = XML::LibXSLT::Singleton->instance;
my $doc = $xml->parse_xml_string("<root/>");
my $root = $doc->getDocumentElement;
$root->appendHash({ name => 'Michael', email => 'mjs@beebo.org' });
DESCRIPTION
ADDED FUNCTIONS
- $xml = parse_xml_file($filename)
- $xml = parse_xml_string($string)
- $xml = parse_xml_chunk($string)
-
Parses a file or string, and returns an XML::LibXML::Document (parse_xml_file(), parse_xml_string()) or XML::LibXML::DocumentFragment (parse_xml_chunk()).
That is, the equivalent of XML::LibXML::Singleton->instance->parse_file($filename), etc.
- $xsl = parse_xslt_file($filename)
- $xsl = parse_xslt_string($string)
-
Parses a file or string, and returns an XML::LibXSLT::Stylesheet. (XML::LibXSLT.)
That is, the equivalent of XML::LibXSLT::Singleton->instance->parse_stylesheet(XML::LibXML::Singleton->instance->parse_file($filename)), etc.
ADDED CLASSES
XML::LibXML::Singleton
Singleton version of XML::LibXML; get an instance via XML::LibXML::SIngleton->instance
.
Note that the methods load_ext_dtd(0)
and validation(0)
have been called on the returned object; see XML::LibXML
for futher details.
XML::LibXSLT::Singleton
Singleton version of XML::LibXSLT; get an instance via XML::LibXSLT::SIngleton->instance
.
ADDED METHODS
TO XML::LibXML::Node
- $n->appendHash( $hash [, $values_are_text ])
-
Converts
$hash
to an XML element, and adds it to$n
. (That is, the opposite of$hash = $n->toHash
.)If
$values_are_text
is 1, the values of the hash are treated as text, and are XML-encoded (&
to&
and so forth) before being added to the node.If
$values_are_text
is 0 or undefined, the values of the hash are treated as XML, and are parsed before being added to the node. In this case, the key values must be either be well-formed XML, or well-balanced XML chunks. (i.e. "<foo/><bar/>" is okay, but not "<foo>".) If neither is true, a comment will be inserted in the place of value--NOT BALANCED XML
.For example, if
$hash = { name => "Clive", email => "clive@example.com", };
and
$node
is
<row> </row>
then
$node->appendHash($hash);
results in the
$node
<row> <name>Clive</name> <email>clive@example.com</email> </row>
NOTE: attribute names (i.e. key values) are lowercased.
- $n->appendAttributeHash( $hash )
-
Adds attributes to node
$n
. - $h = $n->toHash( [ $values_are_text ] )
-
Returns a simple hash reference representation of node
$n
. (That is, the opposite of$n->appendHash($h)
.)If
$values_are_text
is 1, an XML decoding of the values is performed. (&
to&
, etc.)If
$values_are_text
is 0 or undefined, then no transformation of the values are performed.For example, when
toHash()
is called on therow
node<row> <name>Michael</name> <email>mjs@beebo.org</email> </row>
the return value will be
{ name => 'Michael', email => 'mjs@beebo.org', }
NOTE:
- o
-
order is not necessarily preserved, and if two or more tags of the same name are present, only one will be present in the hash.
- o
-
attributes are discarded.
- $h = $n->toAttributeHash
- $n->appendRow($hash [, $name ])
-
Similar to
appendHash($hash)
except that the appended hash is added as child of a$name
element. That is, if$n
is the node "<root/>",$n->appendRow({ name => 'Michael' }, "row")
results in<root> <row> <name>Michael</name> </row> </root>
$name
defaults to "row". - $s = $n->childrenToString
-
Like
toString()
except that only the node's children are stringified--the opening and closing tags of the node itself are omitted. (This may create a "balanced chunk.")
AUTHOR
Michael Stillwell <mjs@beebo.org>
# OLD CODE
sub toHash_can_recurse { my ($self, $recursive) = @_;
$recursive = 0 unless defined $recursive;
my @children = grep { $_->nodeType == XML_ELEMENT_NODE }
$self->childNodes;
if (@children) {
# WE GET HERE IF: THERE'S AT LEAST ONE ELEMENT NODE.
#
# NOTE: THE FOLLOWING SECTIONS, BY PROCESSING ONLY @children,
# PROCESS ONLY ELEMENT NODES--ANY TEXT NODES THAT MAY HAVE
# BEEN CHILDREN OF $self (E.G. IN THE CASE OF MIXED CONTENT)
# ARE IGNORED.
if ($recursive) {
return {
map { $_->nodeName, $_->toHash($recursive) }
@children
};
}
else {
return {
map { $_->nodeName, $_->childrenToString }
@children
};
}
}
else {
# WE GET HERE IF: THERE'S EITHER NO CHILDREN, OR NO CHILDREN
# THAT ARE ELEMENT NODES. (WE ASSUME THAT IN THE LATTER
# CASE, THERE'S ONE CHILD, AND IT'S A TEXT NODE.)
return $self->hasChildNodes ? $self->firstChild->toString : '';
}
}
sub appendHash_old { my ($self, $hash, $values_are_xml) = @_;
$values_are_xml = 1 unless defined $values_are_xml;
my $doc = $self->getOwnerDocument;
while (my ($k, $v) = each %$hash) {
my $n = $doc->createElement(lc($k));
if (defined $v) {
if (!ref($v)) {
if ($values_are_xml) {
my $c = eval {
XML::LibXML::Singleton->instance->parse_balanced_chunk(
$v
);
};
if ($@) {
# COULDN'T PARSE $v
$n->appendChild($doc->createComment(
"VALUE NOT BALANCED XML"
));
}
else {
# COULD PARSE $v
$n->appendChild($doc->adoptNode(
$c
));
}
}
else {
$n->appendChild($doc->createTextNode($v));
}
}
elsif (ref($v) eq "HASH") {
$n->appendHash($v, $values_are_xml);
}
else {
# SOME OTHER SORT OF REFERENCE, SKIP IT (SILENTLY)
}
}
$self->appendChild($n);
}
$hash; # because $n->appendChild($c) returns $c
}