Ticket #26602: XML-TreeBuilder-NoExpand.patch

File XML-TreeBuilder-NoExpand.patch, 8.4 KB (added by r@…, 14 years ago)
  • Changes

    diff -rubB --exclude=.svn --exclude='*.swp' XML-TreeBuilder-3.09/Changes XML-TreeBuilder-patched/Changes
    old new  
    1 # Time-stamp: "2004-06-10 20:28:41 ADT"
     12009-16-03 Jeff Fearn <jfearn@redhat.com>
    22
     3   Release 3.09.x
     4
     5   Added NoExpand option to allow entities to be left untouched in xml.
     6   Added ErrorContext option to allow better reporting of error locations.
     7   Expanded tests to test these options.
    38
    492004-06-10   Sean M. Burke <sburke@cpan.org>
    510
  • lib/XML/TreeBuilder.pm

    diff -rubB --exclude=.svn --exclude='*.swp' XML-TreeBuilder-3.09/lib/XML/TreeBuilder.pm XML-TreeBuilder-patched/lib/XML/TreeBuilder.pm
    old new  
    57use strict;
    68use XML::Element ();
    79use XML::Parser ();
     10use Carp;
    811use vars qw(@ISA $VERSION);
    912
    1013$VERSION = '3.09';
     
    1215
    1316#==========================================================================
    1417sub new {
    15   my $class = ref($_[0]) || $_[0];
    16   # that's the only parameter it knows
     18    my ( $this, $arg ) = @_;
     19    my $class = ref($this) || $this;
     20
     21    my $NoExpand     = ( delete $arg->{'NoExpand'}     || undef );
     22    my $ErrorContext = ( delete $arg->{'ErrorContext'} || undef );
     23
     24    if ( %{$arg} ) {
     25        croak "unknown args: " . join( ", ", keys %{$arg} );
     26    }
    1727 
    1828  my $self = XML::Element->new('NIL');
    1929  bless $self, $class; # and rebless
     
    2131  $self->{'_store_comments'}     = 0;
    2232  $self->{'_store_pis'}          = 0;
    2333  $self->{'_store_declarations'} = 0;
     34    $self->{'NoExpand'}            = $NoExpand if ($NoExpand);
     35    $self->{'ErrorContext'}        = $ErrorContext if ($ErrorContext);
    2436 
    2537  my @stack;
     38
    2639  # Compare the simplicity of this to the sheer nastiness of HTML::TreeBuilder!
    2740 
    28   $self->{'_xml_parser'} = XML::Parser->new( 'Handlers' => {
     41    $self->{'_xml_parser'} = XML::Parser->new(
     42        'Handlers' => {
     43            'Default' => sub {
     44                if ( ( $self->{'NoExpand'} ) && ( $_[1] =~ /&.*\;/ ) ) {
     45                    $stack[-1]->push_content( $_[1] );
     46                }
     47                return;
     48            },
    2949    'Start' => sub {
    3050      shift;
    31       if(@stack) {
     51                if (@stack) {
    3252         push @stack, $self->{'_element_class'}->new(@_);
    3353         $stack[-2]->push_content( $stack[-1] );
    34        } else {
     54                }
     55                else {
    3556         $self->tag(shift);
    36          while(@_) { $self->attr(splice(@_,0,2)) };
     57                    while (@_) { $self->attr( splice( @_, 0, 2 ) ) }
    3758         push @stack, $self;
    3859       }
    3960    },
    4061   
    4162    'End'  => sub { pop @stack; return },
    4263   
    43     'Char' => sub { $stack[-1]->push_content($_[1]) },
     64            'Char' => sub { $stack[-1]->push_content( $_[1] ) },
    4465   
    4566    'Comment' => sub {
    4667       return unless $self->{'_store_comments'};
    47        (
    48         @stack ? $stack[-1] : $self
    49        )->push_content(
    50          $self->{'_element_class'}->new('~comment', 'text' => $_[1])
    51        );
     68                ( @stack ? $stack[-1] : $self )
     69                    ->push_content( $self->{'_element_class'}
     70                        ->new( '~comment', 'text' => $_[1] ) );
    5271       return;
    5372    },
    5473   
    5574    'Proc' => sub {
    5675       return unless $self->{'_store_pis'};
    57        (
    58         @stack ? $stack[-1] : $self
    59        )->push_content(
    60          $self->{'_element_class'}->new('~pi', 'text' => "$_[1] $_[2]")
    61        );
     76                ( @stack ? $stack[-1] : $self )
     77                    ->push_content( $self->{'_element_class'}
     78                        ->new( '~pi', 'text' => "$_[1] $_[2]" ) );
    6279       return;
    6380    },
    6481   
     82            'Final' => sub {
     83                $self->root()->traverse(
     84                    sub {
     85                        my ( $node, $start ) = @_;
     86                        if ( ref $node ) {    # it's an element
     87                            $node->attr( 'NoExpand',     undef );
     88                            $node->attr( 'ErrorContext', undef );
     89                        }
     90                    }
     91                );
     92            },
     93
    6594    # And now, declarations:
    6695   
    6796    'Attlist' => sub {
    6897       return unless $self->{'_store_declarations'};
    6998       shift;
    70        (
    71         @stack ? $stack[-1] : $self
    72        )->push_content(
    73          $self->{'_element_class'}->new('~declaration',
    74           'text' => join ' ', 'ATTLIST', @_
     99                ( @stack ? $stack[-1] : $self )->push_content(
     100                    $self->{'_element_class'}->new(
     101                        '~declaration',
     102                        'text' => join ' ',
     103                        'ATTLIST', @_
    75104         )
    76105       );
    77106       return;
     
    80109    'Element' => sub {
    81110       return unless $self->{'_store_declarations'};
    82111       shift;
    83        (
    84         @stack ? $stack[-1] : $self
    85        )->push_content(
    86          $self->{'_element_class'}->new('~declaration',
    87           'text' => join ' ', 'ELEMENT', @_
     112                ( @stack ? $stack[-1] : $self )->push_content(
     113                    $self->{'_element_class'}->new(
     114                        '~declaration',
     115                        'text' => join ' ',
     116                        'ELEMENT', @_
    88117         )
    89118       );
    90119       return;
     
    93122    'Doctype' => sub {
    94123       return unless $self->{'_store_declarations'};
    95124       shift;
    96        (
    97         @stack ? $stack[-1] : $self
    98        )->push_content(
    99          $self->{'_element_class'}->new('~declaration',
    100           'text' => join ' ', 'DOCTYPE', @_
     125                ( @stack ? $stack[-1] : $self )->push_content(
     126                    $self->{'_element_class'}->new(
     127                        '~declaration',
     128                        'text' => join ' ',
     129                        'DOCTYPE', @_
    101130         )
    102131       );
    103132       return;
    104133    },
    105134   
    106   });
     135            'Entity' => sub {
     136                return unless $self->{'_store_declarations'};
     137                shift;
     138                ( @stack ? $stack[-1] : $self )->push_content(
     139                    $self->{'_element_class'}->new(
     140                        '~declaration',
     141                        'text' => join ' ',
     142                        'ENTITY', @_
     143                    )
     144                );
     145                return;
     146            },
     147        },
     148        'NoExpand'     => $self->{'NoExpand'},
     149        'ErrorContext' => $self->{'ErrorContext'}
     150    );
    107151 
    108152  return $self;
    109153}
     
    110155#==========================================================================
    111156sub _elem # universal accessor...
    112157{
    113   my($self, $elem, $val) = @_;
     158    my ( $self, $elem, $val ) = @_;
    114159  my $old = $self->{$elem};
    115160  $self->{$elem} = $val if defined $val;
    116161  return $old;
    117162}
    118163
    119 sub store_comments { shift->_elem('_store_comments', @_); }
    120 sub store_declarations { shift->_elem('_store_declarations', @_); }
    121 sub store_pis      { shift->_elem('_store_pis', @_); }
     164sub store_comments     { shift->_elem( '_store_comments',     @_ ); }
     165sub store_declarations { shift->_elem( '_store_declarations', @_ ); }
     166sub store_pis          { shift->_elem( '_store_pis',          @_ ); }
    122167
    123168#==========================================================================
    124169
  • t/10main.t

    diff -rubB --exclude=.svn --exclude='*.swp' XML-TreeBuilder-3.09/t/10main.t XML-TreeBuilder-patched/t/10main.t
    old new  
    22# Time-stamp: "2004-06-10 20:22:53 ADT"
    33
    44use Test;
    5 BEGIN { plan tests => 3 }
     5BEGIN { plan tests => 4 }
    66
    77use XML::TreeBuilder;
    88
     
    2929 ]
    3030);
    3131
    32 
    33 ok $x->same_as($y);
     32ok($x->same_as($y));
    3433
    3534unless( $ENV{'HARNESS_ACTIVE'} ) {
    3635  $x->dump;
     
    4344$x->delete;
    4445$y->delete;
    4546
     47$x = XML::TreeBuilder->new({ 'NoExpand' => "1", 'ErrorContext' => "2" });
     48$x->store_comments(1);
     49$x->store_pis(1);
     50$x->store_declarations(1);
     51$x->parse(
     52  qq{<!-- myorp --><Gee><foo Id="me" xml:foo="lal">Hello World</foo>} .
     53  qq{<lor/><!-- foo --></Gee><!-- glarg -->}
     54);
     55
     56$y = XML::Element->new_from_lol(
     57 ['Gee',
     58   ['~comment', {'text' => ' myorp '}],
     59   ['foo', {'Id'=> 'me', 'xml:foo' => 'lal'}, 'Hello World'],
     60   ['lor'],
     61   ['~comment', {'text' => ' foo '}],
     62   ['~comment', {'text' => ' glarg '}],
     63 ]
     64);
     65
     66ok($x->same_as($y));
     67
    4668ok 1;
    4769print "# Bye from ", __FILE__, "\n";