Initial Commit
This commit is contained in:
335
database/perl/vendor/lib/XML/LibXML/SAX/Builder.pm
vendored
Normal file
335
database/perl/vendor/lib/XML/LibXML/SAX/Builder.pm
vendored
Normal file
@@ -0,0 +1,335 @@
|
||||
# $Id$
|
||||
#
|
||||
# This is free software, you may use it and distribute it under the same terms as
|
||||
# Perl itself.
|
||||
#
|
||||
# Copyright 2001-2003 AxKit.com Ltd., 2002-2006 Christian Glahn, 2006-2009 Petr Pajas
|
||||
#
|
||||
#
|
||||
|
||||
package XML::LibXML::SAX::Builder;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use XML::LibXML;
|
||||
use XML::NamespaceSupport;
|
||||
|
||||
use vars qw ($VERSION);
|
||||
|
||||
sub CLONE_SKIP {
|
||||
return $XML::LibXML::__threads_shared ? 0 : 1;
|
||||
}
|
||||
|
||||
$VERSION = "2.0206"; # VERSION TEMPLATE: DO NOT CHANGE
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
return bless {@_}, $class;
|
||||
}
|
||||
|
||||
sub result { $_[0]->{LAST_DOM}; }
|
||||
|
||||
sub done {
|
||||
my ($self) = @_;
|
||||
my $dom = $self->{DOM};
|
||||
$dom = $self->{Parent} unless defined $dom; # this is for parsing document chunks
|
||||
|
||||
delete $self->{NamespaceStack};
|
||||
delete $self->{Parent};
|
||||
delete $self->{DOM};
|
||||
|
||||
$self->{LAST_DOM} = $dom;
|
||||
|
||||
return $dom;
|
||||
}
|
||||
|
||||
sub set_document_locator {
|
||||
}
|
||||
|
||||
sub start_dtd {
|
||||
my ($self, $dtd) = @_;
|
||||
if (defined $dtd->{Name} and
|
||||
(defined $dtd->{SystemId} or defined $dtd->{PublicId})) {
|
||||
$self->{DOM}->createExternalSubset($dtd->{Name},$dtd->{PublicId},$dtd->{SystemId});
|
||||
}
|
||||
}
|
||||
|
||||
sub end_dtd {
|
||||
}
|
||||
|
||||
sub start_document {
|
||||
my ($self, $doc) = @_;
|
||||
$self->{DOM} = XML::LibXML::Document->createDocument();
|
||||
|
||||
if ( defined $self->{Encoding} ) {
|
||||
$self->xml_decl({Version => ($self->{Version} || '1.0') , Encoding => $self->{Encoding}});
|
||||
}
|
||||
|
||||
$self->{NamespaceStack} = XML::NamespaceSupport->new;
|
||||
$self->{NamespaceStack}->push_context;
|
||||
$self->{Parent} = undef;
|
||||
return ();
|
||||
}
|
||||
|
||||
sub xml_decl {
|
||||
my $self = shift;
|
||||
my $decl = shift;
|
||||
|
||||
if ( defined $decl->{Version} ) {
|
||||
$self->{DOM}->setVersion( $decl->{Version} );
|
||||
}
|
||||
if ( defined $decl->{Encoding} ) {
|
||||
$self->{DOM}->setEncoding( $decl->{Encoding} );
|
||||
}
|
||||
return ();
|
||||
}
|
||||
|
||||
sub end_document {
|
||||
my ($self, $doc) = @_;
|
||||
my $d = $self->done();
|
||||
return $d;
|
||||
}
|
||||
|
||||
sub start_prefix_mapping {
|
||||
my $self = shift;
|
||||
my $ns = shift;
|
||||
|
||||
unless ( defined $self->{DOM} or defined $self->{Parent} ) {
|
||||
$self->{Parent} = XML::LibXML::DocumentFragment->new();
|
||||
$self->{NamespaceStack} = XML::NamespaceSupport->new;
|
||||
$self->{NamespaceStack}->push_context;
|
||||
}
|
||||
|
||||
$self->{USENAMESPACESTACK} = 1;
|
||||
|
||||
$self->{NamespaceStack}->declare_prefix( $ns->{Prefix}, $ns->{NamespaceURI} );
|
||||
return ();
|
||||
}
|
||||
|
||||
|
||||
sub end_prefix_mapping {
|
||||
my $self = shift;
|
||||
my $ns = shift;
|
||||
$self->{NamespaceStack}->undeclare_prefix( $ns->{Prefix} );
|
||||
return ();
|
||||
}
|
||||
|
||||
|
||||
sub start_element {
|
||||
my ($self, $el) = @_;
|
||||
my $node;
|
||||
|
||||
unless ( defined $self->{DOM} or defined $self->{Parent} ) {
|
||||
$self->{Parent} = XML::LibXML::DocumentFragment->new();
|
||||
$self->{NamespaceStack} = XML::NamespaceSupport->new;
|
||||
$self->{NamespaceStack}->push_context;
|
||||
}
|
||||
|
||||
if ( defined $self->{Parent} ) {
|
||||
$el->{NamespaceURI} ||= "";
|
||||
$node = $self->{Parent}->addNewChild( $el->{NamespaceURI},
|
||||
$el->{Name} );
|
||||
}
|
||||
else {
|
||||
if ($el->{NamespaceURI}) {
|
||||
if ( defined $self->{DOM} ) {
|
||||
$node = $self->{DOM}->createRawElementNS($el->{NamespaceURI},
|
||||
$el->{Name});
|
||||
}
|
||||
else {
|
||||
$node = XML::LibXML::Element->new( $el->{Name} );
|
||||
$node->setNamespace( $el->{NamespaceURI},
|
||||
$el->{Prefix} , 1 );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( defined $self->{DOM} ) {
|
||||
$node = $self->{DOM}->createRawElement($el->{Name});
|
||||
}
|
||||
else {
|
||||
$node = XML::LibXML::Element->new( $el->{Name} );
|
||||
}
|
||||
}
|
||||
|
||||
$self->{DOM}->setDocumentElement($node);
|
||||
}
|
||||
|
||||
# build namespaces
|
||||
my $skip_ns= 0;
|
||||
foreach my $p ( $self->{NamespaceStack}->get_declared_prefixes() ) {
|
||||
$skip_ns= 1;
|
||||
my $uri = $self->{NamespaceStack}->get_uri($p);
|
||||
my $nodeflag = 0;
|
||||
if ( defined $uri
|
||||
and defined $el->{NamespaceURI}
|
||||
and $uri eq $el->{NamespaceURI} ) {
|
||||
# $nodeflag = 1;
|
||||
next;
|
||||
}
|
||||
$node->setNamespace($uri, $p, 0 );
|
||||
}
|
||||
|
||||
$self->{Parent} = $node;
|
||||
|
||||
$self->{NamespaceStack}->push_context;
|
||||
|
||||
# do attributes
|
||||
foreach my $key (keys %{$el->{Attributes}}) {
|
||||
my $attr = $el->{Attributes}->{$key};
|
||||
if (ref($attr)) {
|
||||
# catch broken name/value pairs
|
||||
next unless $attr->{Name} ;
|
||||
next if $self->{USENAMESPACESTACK}
|
||||
and ( $attr->{Name} eq "xmlns"
|
||||
or ( defined $attr->{Prefix}
|
||||
and $attr->{Prefix} eq "xmlns" ) );
|
||||
|
||||
|
||||
if ( defined $attr->{Prefix}
|
||||
and $attr->{Prefix} eq "xmlns" and $skip_ns == 0 ) {
|
||||
# ok, the generator does not set namespaces correctly!
|
||||
my $uri = $attr->{Value};
|
||||
$node->setNamespace($uri,
|
||||
$attr->{LocalName},
|
||||
$uri eq $el->{NamespaceURI} ? 1 : 0 );
|
||||
}
|
||||
else {
|
||||
$node->setAttributeNS($attr->{NamespaceURI} || "",
|
||||
$attr->{Name}, $attr->{Value});
|
||||
}
|
||||
}
|
||||
else {
|
||||
$node->setAttribute($key => $attr);
|
||||
}
|
||||
}
|
||||
return ();
|
||||
}
|
||||
|
||||
sub end_element {
|
||||
my ($self, $el) = @_;
|
||||
return unless $self->{Parent};
|
||||
|
||||
$self->{NamespaceStack}->pop_context;
|
||||
$self->{Parent} = $self->{Parent}->parentNode();
|
||||
return ();
|
||||
}
|
||||
|
||||
sub start_cdata {
|
||||
my $self = shift;
|
||||
$self->{IN_CDATA} = 1;
|
||||
return ();
|
||||
}
|
||||
|
||||
sub end_cdata {
|
||||
my $self = shift;
|
||||
$self->{IN_CDATA} = 0;
|
||||
return ();
|
||||
}
|
||||
|
||||
sub characters {
|
||||
my ($self, $chars) = @_;
|
||||
if ( not defined $self->{DOM} and not defined $self->{Parent} ) {
|
||||
$self->{Parent} = XML::LibXML::DocumentFragment->new();
|
||||
$self->{NamespaceStack} = XML::NamespaceSupport->new;
|
||||
$self->{NamespaceStack}->push_context;
|
||||
}
|
||||
return unless $self->{Parent};
|
||||
my $node;
|
||||
|
||||
unless ( defined $chars and defined $chars->{Data} ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( defined $self->{DOM} ) {
|
||||
if ( defined $self->{IN_CDATA} and $self->{IN_CDATA} == 1 ) {
|
||||
$node = $self->{DOM}->createCDATASection($chars->{Data});
|
||||
}
|
||||
else {
|
||||
$node = $self->{Parent}->appendText($chars->{Data});
|
||||
return;
|
||||
}
|
||||
}
|
||||
elsif ( defined $self->{IN_CDATA} and $self->{IN_CDATA} == 1 ) {
|
||||
$node = XML::LibXML::CDATASection->new($chars->{Data});
|
||||
}
|
||||
else {
|
||||
$node = XML::LibXML::Text->new($chars->{Data});
|
||||
}
|
||||
|
||||
$self->{Parent}->addChild($node);
|
||||
return ();
|
||||
}
|
||||
|
||||
sub comment {
|
||||
my ($self, $chars) = @_;
|
||||
my $comment;
|
||||
if ( not defined $self->{DOM} and not defined $self->{Parent} ) {
|
||||
$self->{Parent} = XML::LibXML::DocumentFragment->new();
|
||||
$self->{NamespaceStack} = XML::NamespaceSupport->new;
|
||||
$self->{NamespaceStack}->push_context;
|
||||
}
|
||||
|
||||
unless ( defined $chars and defined $chars->{Data} ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( defined $self->{DOM} ) {
|
||||
$comment = $self->{DOM}->createComment( $chars->{Data} );
|
||||
}
|
||||
else {
|
||||
$comment = XML::LibXML::Comment->new( $chars->{Data} );
|
||||
}
|
||||
|
||||
if ( defined $self->{Parent} ) {
|
||||
$self->{Parent}->addChild($comment);
|
||||
}
|
||||
else {
|
||||
$self->{DOM}->addChild($comment);
|
||||
}
|
||||
return ();
|
||||
}
|
||||
|
||||
sub processing_instruction {
|
||||
my ( $self, $pi ) = @_;
|
||||
my $PI;
|
||||
return unless defined $self->{DOM};
|
||||
$PI = $self->{DOM}->createPI( $pi->{Target}, $pi->{Data} );
|
||||
|
||||
if ( defined $self->{Parent} ) {
|
||||
$self->{Parent}->addChild( $PI );
|
||||
}
|
||||
else {
|
||||
$self->{DOM}->addChild( $PI );
|
||||
}
|
||||
return ();
|
||||
}
|
||||
|
||||
sub warning {
|
||||
my $self = shift;
|
||||
my $error = shift;
|
||||
# fill $@ but do not die seriously
|
||||
eval { $error->throw; };
|
||||
}
|
||||
|
||||
sub error {
|
||||
my $self = shift;
|
||||
my $error = shift;
|
||||
delete $self->{NamespaceStack};
|
||||
delete $self->{Parent};
|
||||
delete $self->{DOM};
|
||||
$error->throw;
|
||||
}
|
||||
|
||||
sub fatal_error {
|
||||
my $self = shift;
|
||||
my $error = shift;
|
||||
delete $self->{NamespaceStack};
|
||||
delete $self->{Parent};
|
||||
delete $self->{DOM};
|
||||
$error->throw;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
58
database/perl/vendor/lib/XML/LibXML/SAX/Builder.pod
vendored
Normal file
58
database/perl/vendor/lib/XML/LibXML/SAX/Builder.pod
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
=head1 NAME
|
||||
|
||||
XML::LibXML::SAX::Builder - Building DOM trees from SAX events.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
use XML::LibXML::SAX::Builder;
|
||||
my $builder = XML::LibXML::SAX::Builder->new();
|
||||
|
||||
my $gen = XML::Generator::DBI->new(Handler => $builder, dbh => $dbh);
|
||||
$gen->execute("SELECT * FROM Users");
|
||||
|
||||
my $doc = $builder->result();
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is a SAX handler that generates a DOM tree from SAX events. Usage is as
|
||||
above. Input is accepted from any SAX1 or SAX2 event generator.
|
||||
|
||||
Building DOM trees from SAX events is quite easy with
|
||||
XML::LibXML::SAX::Builder. The class is designed as a SAX2 final handler not as
|
||||
a filter!
|
||||
|
||||
Since SAX is strictly stream oriented, you should not expect anything to return
|
||||
from a generator. Instead you have to ask the builder instance directly to get
|
||||
the document built. XML::LibXML::SAX::Builder's result() function holds the
|
||||
document generated from the last SAX stream.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Matt Sergeant,
|
||||
Christian Glahn,
|
||||
Petr Pajas
|
||||
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
2.0206
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
2001-2007, AxKit.com Ltd.
|
||||
|
||||
2002-2006, Christian Glahn.
|
||||
|
||||
2006-2009, Petr Pajas.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the same terms as Perl itself.
|
||||
|
||||
158
database/perl/vendor/lib/XML/LibXML/SAX/Generator.pm
vendored
Normal file
158
database/perl/vendor/lib/XML/LibXML/SAX/Generator.pm
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
# $Id: Generator.pm 772 2009-01-23 21:42:09Z pajas
|
||||
#
|
||||
# This is free software, you may use it and distribute it under the same terms as
|
||||
# Perl itself.
|
||||
#
|
||||
# Copyright 2001-2003 AxKit.com Ltd., 2002-2006 Christian Glahn, 2006-2009 Petr Pajas
|
||||
#
|
||||
#
|
||||
|
||||
package XML::LibXML::SAX::Generator;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use XML::LibXML;
|
||||
use vars qw ($VERSION);
|
||||
|
||||
$VERSION = "2.0206"; # VERSION TEMPLATE: DO NOT CHANGE
|
||||
|
||||
sub CLONE_SKIP {
|
||||
return $XML::LibXML::__threads_shared ? 0 : 1;
|
||||
}
|
||||
|
||||
warn("This class (", __PACKAGE__, ") is deprecated!");
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
unshift @_, 'Handler' unless @_ != 1;
|
||||
my %p = @_;
|
||||
return bless \%p, $class;
|
||||
}
|
||||
|
||||
sub generate {
|
||||
my $self = shift;
|
||||
my ($node) = @_;
|
||||
|
||||
my $document = { Parent => undef };
|
||||
$self->{Handler}->start_document($document);
|
||||
|
||||
process_node($self->{Handler}, $node);
|
||||
|
||||
$self->{Handler}->end_document($document);
|
||||
}
|
||||
|
||||
sub process_node {
|
||||
my ($handler, $node) = @_;
|
||||
|
||||
my $node_type = $node->getType();
|
||||
if ($node_type == XML_COMMENT_NODE) {
|
||||
$handler->comment( { Data => $node->getData } );
|
||||
}
|
||||
elsif ($node_type == XML_TEXT_NODE || $node_type == XML_CDATA_SECTION_NODE) {
|
||||
# warn($node->getData . "\n");
|
||||
$handler->characters( { Data => $node->getData } );
|
||||
}
|
||||
elsif ($node_type == XML_ELEMENT_NODE) {
|
||||
# warn("<" . $node->getName . ">\n");
|
||||
process_element($handler, $node);
|
||||
# warn("</" . $node->getName . ">\n");
|
||||
}
|
||||
elsif ($node_type == XML_ENTITY_REF_NODE) {
|
||||
foreach my $kid ($node->getChildnodes) {
|
||||
# warn("child of entity ref: " . $kid->getType() . " called: " . $kid->getName . "\n");
|
||||
process_node($handler, $kid);
|
||||
}
|
||||
}
|
||||
elsif ($node_type == XML_DOCUMENT_NODE) {
|
||||
# just get root element. Ignore other cruft.
|
||||
foreach my $kid ($node->getChildnodes) {
|
||||
if ($kid->getType() == XML_ELEMENT_NODE) {
|
||||
process_element($handler, $kid);
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
warn("unknown node type: $node_type");
|
||||
}
|
||||
}
|
||||
|
||||
sub process_element {
|
||||
my ($handler, $element) = @_;
|
||||
|
||||
my @attr;
|
||||
|
||||
foreach my $attr ($element->getAttributes) {
|
||||
push @attr, XML::LibXML::SAX::AttributeNode->new(
|
||||
Name => $attr->getName,
|
||||
Value => $attr->getData,
|
||||
NamespaceURI => $attr->getNamespaceURI,
|
||||
Prefix => $attr->getPrefix,
|
||||
LocalName => $attr->getLocalName,
|
||||
);
|
||||
}
|
||||
|
||||
my $node = {
|
||||
Name => $element->getName,
|
||||
Attributes => { map { $_->{Name} => $_ } @attr },
|
||||
NamespaceURI => $element->getNamespaceURI,
|
||||
Prefix => $element->getPrefix,
|
||||
LocalName => $element->getLocalName,
|
||||
};
|
||||
|
||||
$handler->start_element($node);
|
||||
|
||||
foreach my $child ($element->getChildnodes) {
|
||||
process_node($handler, $child);
|
||||
}
|
||||
|
||||
$handler->end_element($node);
|
||||
}
|
||||
|
||||
package XML::LibXML::SAX::AttributeNode;
|
||||
|
||||
use overload '""' => "stringify";
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my %p = @_;
|
||||
return bless \%p, $class;
|
||||
}
|
||||
|
||||
sub stringify {
|
||||
my $self = shift;
|
||||
return $self->{Value};
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
XML::LibXML::SAX::Generator - Generate SAX events from a LibXML tree
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $handler = MySAXHandler->new();
|
||||
my $generator = XML::LibXML::SAX::Generator->new(Handler => $handler);
|
||||
my $dom = XML::LibXML->new->parse_file("foo.xml");
|
||||
|
||||
$generator->generate($dom);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
THIS CLASS IS DEPRECATED! Use XML::LibXML::SAX::Parser instead!
|
||||
|
||||
This helper class allows you to generate SAX events from any XML::LibXML
|
||||
node, and all it's sub-nodes. This basically gives you interop from
|
||||
XML::LibXML to other modules that may implement SAX.
|
||||
|
||||
It uses SAX2 style, but should be compatible with anything SAX1, by use
|
||||
of stringification overloading.
|
||||
|
||||
There is nothing to really know about, beyond the synopsis above, and
|
||||
a general knowledge of how to use SAX, which is beyond the scope here.
|
||||
|
||||
=cut
|
||||
266
database/perl/vendor/lib/XML/LibXML/SAX/Parser.pm
vendored
Normal file
266
database/perl/vendor/lib/XML/LibXML/SAX/Parser.pm
vendored
Normal file
@@ -0,0 +1,266 @@
|
||||
# $Id$
|
||||
#
|
||||
# This is free software, you may use it and distribute it under the same terms as
|
||||
# Perl itself.
|
||||
#
|
||||
# Copyright 2001-2003 AxKit.com Ltd., 2002-2006 Christian Glahn, 2006-2009 Petr Pajas
|
||||
#
|
||||
#
|
||||
|
||||
package XML::LibXML::SAX::Parser;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use vars qw($VERSION @ISA);
|
||||
|
||||
use XML::LibXML;
|
||||
use XML::LibXML::Common qw(:libxml);
|
||||
use XML::SAX::Base;
|
||||
use XML::SAX::DocumentLocator;
|
||||
|
||||
$VERSION = "2.0206"; # VERSION TEMPLATE: DO NOT CHANGE
|
||||
@ISA = ('XML::SAX::Base');
|
||||
|
||||
sub CLONE_SKIP {
|
||||
return $XML::LibXML::__threads_shared ? 0 : 1;
|
||||
}
|
||||
|
||||
sub _parse_characterstream {
|
||||
my ($self, $fh, $options) = @_;
|
||||
die "parsing a characterstream is not supported at this time";
|
||||
}
|
||||
|
||||
sub _parse_bytestream {
|
||||
my ($self, $fh, $options) = @_;
|
||||
my $parser = XML::LibXML->new();
|
||||
my $doc = exists($options->{Source}{SystemId}) ? $parser->parse_fh($fh, $options->{Source}{SystemId}) : $parser->parse_fh($fh);
|
||||
$self->generate($doc);
|
||||
}
|
||||
|
||||
sub _parse_string {
|
||||
my ($self, $str, $options) = @_;
|
||||
my $parser = XML::LibXML->new();
|
||||
my $doc = exists($options->{Source}{SystemId}) ? $parser->parse_string($str, $options->{Source}{SystemId}) : $parser->parse_string($str);
|
||||
$self->generate($doc);
|
||||
}
|
||||
|
||||
sub _parse_systemid {
|
||||
my ($self, $sysid, $options) = @_;
|
||||
my $parser = XML::LibXML->new();
|
||||
my $doc = $parser->parse_file($sysid);
|
||||
$self->generate($doc);
|
||||
}
|
||||
|
||||
sub generate {
|
||||
my $self = shift;
|
||||
my ($node) = @_;
|
||||
|
||||
my $doc = $node->ownerDocument();
|
||||
{
|
||||
# precompute some DocumentLocator values
|
||||
my %locator = (
|
||||
PublicId => undef,
|
||||
SystemId => undef,
|
||||
Encoding => undef,
|
||||
XMLVersion => undef,
|
||||
);
|
||||
my $dtd = defined $doc ? $doc->externalSubset() : undef;
|
||||
if (defined $dtd) {
|
||||
$locator{PublicId} = $dtd->publicId();
|
||||
$locator{SystemId} = $dtd->systemId();
|
||||
}
|
||||
if (defined $doc) {
|
||||
$locator{Encoding} = $doc->encoding();
|
||||
$locator{XMLVersion} = $doc->version();
|
||||
}
|
||||
$self->set_document_locator(
|
||||
XML::SAX::DocumentLocator->new(
|
||||
sub { $locator{PublicId} },
|
||||
sub { $locator{SystemId} },
|
||||
sub { defined($self->{current_node}) ? $self->{current_node}->line_number() : undef },
|
||||
sub { 1 },
|
||||
sub { $locator{Encoding} },
|
||||
sub { $locator{XMLVersion} },
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if ( $node->nodeType() == XML_DOCUMENT_NODE
|
||||
|| $node->nodeType == XML_HTML_DOCUMENT_NODE ) {
|
||||
$self->start_document({});
|
||||
$self->xml_decl({Version => $node->getVersion, Encoding => $node->getEncoding});
|
||||
$self->process_node($node);
|
||||
$self->end_document({});
|
||||
}
|
||||
}
|
||||
|
||||
sub process_node {
|
||||
my ($self, $node) = @_;
|
||||
|
||||
local $self->{current_node} = $node;
|
||||
|
||||
my $node_type = $node->nodeType();
|
||||
if ($node_type == XML_COMMENT_NODE) {
|
||||
$self->comment( { Data => $node->getData } );
|
||||
}
|
||||
elsif ($node_type == XML_TEXT_NODE
|
||||
|| $node_type == XML_CDATA_SECTION_NODE) {
|
||||
# warn($node->getData . "\n");
|
||||
$self->characters( { Data => $node->nodeValue } );
|
||||
}
|
||||
elsif ($node_type == XML_ELEMENT_NODE) {
|
||||
# warn("<" . $node->getName . ">\n");
|
||||
$self->process_element($node);
|
||||
# warn("</" . $node->getName . ">\n");
|
||||
}
|
||||
elsif ($node_type == XML_ENTITY_REF_NODE) {
|
||||
foreach my $kid ($node->childNodes) {
|
||||
# warn("child of entity ref: " . $kid->getType() . " called: " . $kid->getName . "\n");
|
||||
$self->process_node($kid);
|
||||
}
|
||||
}
|
||||
elsif ($node_type == XML_DOCUMENT_NODE
|
||||
|| $node_type == XML_HTML_DOCUMENT_NODE
|
||||
|| $node_type == XML_DOCUMENT_FRAG_NODE) {
|
||||
# sometimes it is just useful to generate SAX events from
|
||||
# a document fragment (very good with filters).
|
||||
foreach my $kid ($node->childNodes) {
|
||||
$self->process_node($kid);
|
||||
}
|
||||
}
|
||||
elsif ($node_type == XML_PI_NODE) {
|
||||
$self->processing_instruction( { Target => $node->getName, Data => $node->getData } );
|
||||
}
|
||||
elsif ($node_type == XML_COMMENT_NODE) {
|
||||
$self->comment( { Data => $node->getData } );
|
||||
}
|
||||
elsif ( $node_type == XML_XINCLUDE_START
|
||||
|| $node_type == XML_XINCLUDE_END ) {
|
||||
# ignore!
|
||||
# i may want to handle this one day, dunno yet
|
||||
}
|
||||
elsif ($node_type == XML_DTD_NODE ) {
|
||||
# ignore!
|
||||
# i will support DTDs, but had no time yet.
|
||||
}
|
||||
else {
|
||||
# warn("unsupported node type: $node_type");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub process_element {
|
||||
my ($self, $element) = @_;
|
||||
|
||||
my $attribs = {};
|
||||
my @ns_maps = $element->getNamespaces;
|
||||
|
||||
foreach my $ns (@ns_maps) {
|
||||
$self->start_prefix_mapping(
|
||||
{
|
||||
NamespaceURI => $ns->href,
|
||||
Prefix => ( defined $ns->localname ? $ns->localname : ''),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
foreach my $attr ($element->attributes) {
|
||||
my $key;
|
||||
# warn("Attr: $attr -> ", $attr->getName, " = ", $attr->getData, "\n");
|
||||
# this isa dump thing...
|
||||
if ($attr->isa('XML::LibXML::Namespace')) {
|
||||
# TODO This needs fixing modulo agreeing on what
|
||||
# is the right thing to do here.
|
||||
unless ( defined $attr->name ) {
|
||||
## It's an atter like "xmlns='foo'"
|
||||
$attribs->{"{}xmlns"} =
|
||||
{
|
||||
Name => "xmlns",
|
||||
LocalName => "xmlns",
|
||||
Prefix => "",
|
||||
Value => $attr->href,
|
||||
NamespaceURI => "",
|
||||
};
|
||||
}
|
||||
else {
|
||||
my $prefix = "xmlns";
|
||||
my $localname = $attr->localname;
|
||||
my $key = "{http://www.w3.org/2000/xmlns/}";
|
||||
my $name = "xmlns";
|
||||
|
||||
if ( defined $localname ) {
|
||||
$key .= $localname;
|
||||
$name.= ":".$localname;
|
||||
}
|
||||
|
||||
$attribs->{$key} =
|
||||
{
|
||||
Name => $name,
|
||||
Value => $attr->href,
|
||||
NamespaceURI => "http://www.w3.org/2000/xmlns/",
|
||||
Prefix => $prefix,
|
||||
LocalName => $localname,
|
||||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
my $ns = $attr->namespaceURI;
|
||||
|
||||
$ns = '' unless defined $ns;
|
||||
$key = "{$ns}".$attr->localname;
|
||||
## Not sure why, but $attr->name is coming through stripped
|
||||
## of its prefix, so we need to hand-assemble a real name.
|
||||
my $name = $attr->name;
|
||||
$name = "" unless defined $name;
|
||||
|
||||
my $prefix = $attr->prefix;
|
||||
$prefix = "" unless defined $prefix;
|
||||
$name = "$prefix:$name"
|
||||
if index( $name, ":" ) < 0 && length $prefix;
|
||||
|
||||
$attribs->{$key} =
|
||||
{
|
||||
Name => $name,
|
||||
Value => $attr->value,
|
||||
NamespaceURI => $ns,
|
||||
Prefix => $prefix,
|
||||
LocalName => $attr->localname,
|
||||
};
|
||||
}
|
||||
# use Data::Dumper;
|
||||
# warn("Attr made: ", Dumper($attribs->{$key}), "\n");
|
||||
}
|
||||
|
||||
my $node = {
|
||||
Name => $element->nodeName,
|
||||
Attributes => $attribs,
|
||||
NamespaceURI => $element->namespaceURI,
|
||||
Prefix => $element->prefix || "",
|
||||
LocalName => $element->localname,
|
||||
};
|
||||
|
||||
$self->start_element($node);
|
||||
|
||||
foreach my $child ($element->childNodes) {
|
||||
$self->process_node($child);
|
||||
}
|
||||
|
||||
my $end_node = { %$node };
|
||||
|
||||
delete $end_node->{Attributes};
|
||||
|
||||
$self->end_element($end_node);
|
||||
|
||||
foreach my $ns (@ns_maps) {
|
||||
$self->end_prefix_mapping(
|
||||
{
|
||||
NamespaceURI => $ns->href,
|
||||
Prefix => ( defined $ns->localname ? $ns->localname : ''),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
Reference in New Issue
Block a user