<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;"># $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.0134"; # VERSION TEMPLATE: DO NOT CHANGE

sub new {
    my $class = shift;
    return bless {@_}, $class;
}

sub result { $_[0]-&gt;{LAST_DOM}; }

sub done {
    my ($self) = @_;
    my $dom = $self-&gt;{DOM};
    $dom = $self-&gt;{Parent} unless defined $dom; # this is for parsing document chunks

    delete $self-&gt;{NamespaceStack};
    delete $self-&gt;{Parent};
    delete $self-&gt;{DOM};

    $self-&gt;{LAST_DOM} = $dom;

    return $dom;
}

sub set_document_locator {
}

sub start_dtd {
  my ($self, $dtd) = @_;
  if (defined $dtd-&gt;{Name} and
      (defined $dtd-&gt;{SystemId} or defined $dtd-&gt;{PublicId})) {
    $self-&gt;{DOM}-&gt;createExternalSubset($dtd-&gt;{Name},$dtd-&gt;{PublicId},$dtd-&gt;{SystemId});
  }
}

sub end_dtd {
}

sub start_document {
    my ($self, $doc) = @_;
    $self-&gt;{DOM} = XML::LibXML::Document-&gt;createDocument();

    if ( defined $self-&gt;{Encoding} ) {
        $self-&gt;xml_decl({Version =&gt; ($self-&gt;{Version} || '1.0') , Encoding =&gt; $self-&gt;{Encoding}});
    }

    $self-&gt;{NamespaceStack} = XML::NamespaceSupport-&gt;new;
    $self-&gt;{NamespaceStack}-&gt;push_context;
    $self-&gt;{Parent} = undef;
    return ();
}

sub xml_decl {
    my $self = shift;
    my $decl = shift;

    if ( defined $decl-&gt;{Version} ) {
        $self-&gt;{DOM}-&gt;setVersion( $decl-&gt;{Version} );
    }
    if ( defined $decl-&gt;{Encoding} ) {
        $self-&gt;{DOM}-&gt;setEncoding( $decl-&gt;{Encoding} );
    }
    return ();
}

sub end_document {
    my ($self, $doc) = @_;
    my $d = $self-&gt;done();
    return $d;
}

sub start_prefix_mapping {
    my $self = shift;
    my $ns = shift;

    unless ( defined $self-&gt;{DOM} or defined $self-&gt;{Parent} ) {
        $self-&gt;{Parent} = XML::LibXML::DocumentFragment-&gt;new();
        $self-&gt;{NamespaceStack} = XML::NamespaceSupport-&gt;new;
        $self-&gt;{NamespaceStack}-&gt;push_context;
    }

    $self-&gt;{USENAMESPACESTACK} = 1;

    $self-&gt;{NamespaceStack}-&gt;declare_prefix( $ns-&gt;{Prefix}, $ns-&gt;{NamespaceURI} );
    return ();
}


sub end_prefix_mapping {
    my $self = shift;
    my $ns = shift;
    $self-&gt;{NamespaceStack}-&gt;undeclare_prefix( $ns-&gt;{Prefix} );
    return ();
}


sub start_element {
    my ($self, $el) = @_;
    my $node;

    unless ( defined $self-&gt;{DOM} or defined $self-&gt;{Parent} ) {
        $self-&gt;{Parent} = XML::LibXML::DocumentFragment-&gt;new();
        $self-&gt;{NamespaceStack} = XML::NamespaceSupport-&gt;new;
        $self-&gt;{NamespaceStack}-&gt;push_context;
    }

    if ( defined $self-&gt;{Parent} ) {
        $el-&gt;{NamespaceURI} ||= "";
        $node = $self-&gt;{Parent}-&gt;addNewChild( $el-&gt;{NamespaceURI},
                                              $el-&gt;{Name} );
    }
    else {
        if ($el-&gt;{NamespaceURI}) {
            if ( defined $self-&gt;{DOM} ) {
                $node = $self-&gt;{DOM}-&gt;createRawElementNS($el-&gt;{NamespaceURI},
                                                         $el-&gt;{Name});
            }
            else {
                $node = XML::LibXML::Element-&gt;new( $el-&gt;{Name} );
                $node-&gt;setNamespace( $el-&gt;{NamespaceURI},
                                     $el-&gt;{Prefix} , 1 );
            }
        }
        else {
            if ( defined $self-&gt;{DOM} ) {
                $node = $self-&gt;{DOM}-&gt;createRawElement($el-&gt;{Name});
            }
            else {
                $node = XML::LibXML::Element-&gt;new( $el-&gt;{Name} );
            }
        }

        $self-&gt;{DOM}-&gt;setDocumentElement($node);
    }

    # build namespaces
    my $skip_ns= 0;
    foreach my $p ( $self-&gt;{NamespaceStack}-&gt;get_declared_prefixes() ) {
        $skip_ns= 1;
        my $uri = $self-&gt;{NamespaceStack}-&gt;get_uri($p);
        my $nodeflag = 0;
        if ( defined $uri
             and defined $el-&gt;{NamespaceURI}
             and $uri eq $el-&gt;{NamespaceURI} ) {
            #            $nodeflag = 1;
            next;
        }
        $node-&gt;setNamespace($uri, $p, 0 );
    }

    $self-&gt;{Parent} = $node;

    $self-&gt;{NamespaceStack}-&gt;push_context;

    # do attributes
    foreach my $key (keys %{$el-&gt;{Attributes}}) {
        my $attr = $el-&gt;{Attributes}-&gt;{$key};
        if (ref($attr)) {
            # catch broken name/value pairs
            next unless $attr-&gt;{Name} ;
            next if $self-&gt;{USENAMESPACESTACK}
                    and ( $attr-&gt;{Name} eq "xmlns"
                          or ( defined $attr-&gt;{Prefix}
                               and $attr-&gt;{Prefix} eq "xmlns" ) );


            if ( defined $attr-&gt;{Prefix}
                 and $attr-&gt;{Prefix} eq "xmlns" and $skip_ns == 0 ) {
                # ok, the generator does not set namespaces correctly!
                my $uri = $attr-&gt;{Value};
                $node-&gt;setNamespace($uri,
                                    $attr-&gt;{LocalName},
                                    $uri eq $el-&gt;{NamespaceURI} ? 1 : 0 );
            }
            else {
                $node-&gt;setAttributeNS($attr-&gt;{NamespaceURI} || "",
                                      $attr-&gt;{Name}, $attr-&gt;{Value});
            }
        }
        else {
            $node-&gt;setAttribute($key =&gt; $attr);
        }
    }
    return ();
}

sub end_element {
    my ($self, $el) = @_;
    return unless $self-&gt;{Parent};

    $self-&gt;{NamespaceStack}-&gt;pop_context;
    $self-&gt;{Parent} = $self-&gt;{Parent}-&gt;parentNode();
    return ();
}

sub start_cdata {
    my $self = shift;
    $self-&gt;{IN_CDATA} = 1;
    return ();
}

sub end_cdata {
    my $self = shift;
    $self-&gt;{IN_CDATA} = 0;
    return ();
}

sub characters {
    my ($self, $chars) = @_;
    if ( not defined $self-&gt;{DOM} and not defined $self-&gt;{Parent} ) {
        $self-&gt;{Parent} = XML::LibXML::DocumentFragment-&gt;new();
        $self-&gt;{NamespaceStack} = XML::NamespaceSupport-&gt;new;
        $self-&gt;{NamespaceStack}-&gt;push_context;
    }
    return unless $self-&gt;{Parent};
    my $node;

    unless ( defined $chars and defined $chars-&gt;{Data} ) {
        return;
    }

    if ( defined $self-&gt;{DOM} ) {
        if ( defined $self-&gt;{IN_CDATA} and $self-&gt;{IN_CDATA} == 1 ) {
            $node = $self-&gt;{DOM}-&gt;createCDATASection($chars-&gt;{Data});
        }
        else {
            $node = $self-&gt;{Parent}-&gt;appendText($chars-&gt;{Data});
            return;
        }
    }
    elsif ( defined $self-&gt;{IN_CDATA} and $self-&gt;{IN_CDATA} == 1 ) {
        $node = XML::LibXML::CDATASection-&gt;new($chars-&gt;{Data});
    }
    else {
        $node = XML::LibXML::Text-&gt;new($chars-&gt;{Data});
    }

    $self-&gt;{Parent}-&gt;addChild($node);
    return ();
}

sub comment {
    my ($self, $chars) = @_;
    my $comment;
    if ( not defined $self-&gt;{DOM} and not defined $self-&gt;{Parent} ) {
        $self-&gt;{Parent} = XML::LibXML::DocumentFragment-&gt;new();
        $self-&gt;{NamespaceStack} = XML::NamespaceSupport-&gt;new;
        $self-&gt;{NamespaceStack}-&gt;push_context;
    }

    unless ( defined $chars and defined $chars-&gt;{Data} ) {
        return;
    }

    if ( defined $self-&gt;{DOM} ) {
        $comment = $self-&gt;{DOM}-&gt;createComment( $chars-&gt;{Data} );
    }
    else {
        $comment = XML::LibXML::Comment-&gt;new( $chars-&gt;{Data} );
    }

    if ( defined $self-&gt;{Parent} ) {
        $self-&gt;{Parent}-&gt;addChild($comment);
    }
    else {
        $self-&gt;{DOM}-&gt;addChild($comment);
    }
    return ();
}

sub processing_instruction {
    my ( $self,  $pi ) = @_;
    my $PI;
    return unless  defined $self-&gt;{DOM};
    $PI = $self-&gt;{DOM}-&gt;createPI( $pi-&gt;{Target}, $pi-&gt;{Data} );

    if ( defined $self-&gt;{Parent} ) {
        $self-&gt;{Parent}-&gt;addChild( $PI );
    }
    else {
        $self-&gt;{DOM}-&gt;addChild( $PI );
    }
    return ();
}

sub warning {
    my $self = shift;
    my $error = shift;
    # fill $@ but do not die seriously
    eval { $error-&gt;throw; };
}

sub error {
    my $self = shift;
    my $error = shift;
    delete $self-&gt;{NamespaceStack};
    delete $self-&gt;{Parent};
    delete $self-&gt;{DOM};
    $error-&gt;throw;
}

sub fatal_error {
    my $self = shift;
    my $error = shift;
    delete $self-&gt;{NamespaceStack};
    delete $self-&gt;{Parent};
    delete $self-&gt;{DOM};
    $error-&gt;throw;
}

1;

__END__
</pre></body></html>