package SVG::Parser::Expat; use strict; require 5.004; use base qw(XML::Parser SVG::Parser::Base); use SVG 2.0; use vars qw($VERSION @ISA); $VERSION="1.03"; #--------------------------------------------------------------------------------------- =head1 NAME SVG::Parser::Expat - XML Expat Parser for SVG documents =head1 SYNOPSIS #!/usr/bin/perl -w use strict; use SVG::Parser::Expat; die "Usage: $0 \n" unless @ARGV; my $xml; { local $/=undef; $xml=<>; } my $parser=new SVG::Parser::Expat; my $svg=$parser->parse($xml); print $svg->xmlify; =head1 DESCRIPTION SVG::Parser::Expat is the Expat-specific parser module used by SVG::Parser when an underlying XML::Parser-based parser is selected. It may also be used directly, as shown in the synopsis above. Use SVG::Parser to retain maximum flexibility as to which underlying parser is chosen. Use SVG::Parser::Expat to supply Expat-specific parser options or where the presence of XML::Parser is known and/or preferred. =head2 EXPORTS None. However, an alternative parent class (other than XML::Parser) can be specified by passing the package name to SVG::Parser::Expat in the import list. For example: use SVG::Parser::Expat qw(My::XML::Parser::Subclass); Where My::XML::Parser::Subclass is a subclass like: package My::XML::Parser::Subclass; use strict; use vars qw(@ISA); use XML::Parser; @ISA=qw(XML::Parser); ...custom methods... 1; When loaded via SVG::Parser, this parent class may be specified by placing it after the '=' in a parser specification: use SVG::Parser qw(Expat=My::XML::Parser::Subclass); See L for more details. =head2 EXAMPLES See C in the examples directory of the distribution. =head1 AUTHOR Peter Wainwright, peter.wainwright@cybrid.net =head1 SEE ALSO L, L, L, L =cut #--------------------------------------------------------------------------------------- # SVG::Parser::Expat constructor. Attributes with no minus prefix are passed to # the parent parser class. Attributes with a minus are set locally. sub new { my $proto=shift; my $class=ref($proto) || $proto; my %attrs=@_; # pass on non-minus-prefixed attributes to XML::Parser my %parser_attrs; foreach (keys %attrs) { $parser_attrs{$_}=delete $attrs{$_} unless /^-/; } my $parser=$class->SUPER::new(%parser_attrs); $parser->setHandlers( XMLDecl => sub { XMLDecl($parser, @_) }, Doctype => sub { Doctype($parser, @_) }, Init => sub { StartDocument($parser, @_) }, Final => sub { FinishDocument($parser, @_) }, Start => sub { StartTag($parser, @_) }, End => sub { EndTag($parser, @_) }, Char => sub { Text($parser, @_) }, CdataStart => sub { $parser->SVG::Parser::Base::CdataStart(@_) }, CdataEnd => sub { $parser->SVG::Parser::Base::CdataEnd(@_) }, Proc => sub { PI($parser, @_) }, Comment => sub { Comment($parser, @_) }, Unparsed => sub { Unparsed($parser, @_) }, Notation => sub { Notation($parser,@_) }, Entity => sub { Entity($parser, @_) }, Element => sub { Element($parser,@_) }, Attlist => sub { Attlist($parser,@_) }, ); # minus-prefixed attributes stay here, double-minus to SVG object foreach (keys %attrs) { if (/^-(-.+)$/) { $parser->{__svg_attr}{$1}=$attrs{$_}; } else { $parser->{$_}=$attrs{$_}; } } return $parser; } #--------------------------------------------------------------------------------------- # Import method to change default inheritance, if required sub import { my $package=shift; # permit an alternative XML::Parser subclass to be our parent class if (@_) { my $superclass=shift; $ISA[0]=$superclass,return if eval qq[ use $superclass qw(@_); 1; ]; die "Parent parser class $superclass not found: $@\n"; } } #--------------------------------------------------------------------------------------- # Handlers # create and set SVG document object as root element sub StartDocument { my ($parser,$expat)=@_; return $parser->SVG::Parser::Base::StartDocument(); } # handle start of element - extend chain by one sub StartTag { my ($parser,$expat,$type,%attrs)=@_; return $parser->SVG::Parser::Base::StartTag($type,%attrs); } # handle end of element - shorten chain by one sub EndTag { my ($parser,$expat,$type)=@_; return $parser->SVG::Parser::Base::EndTag($type); } # handle cannonical data (text) sub Text { my ($parser,$expat,$text)=@_; return $parser->SVG::Parser::Base::Text($text); } # handle processing instructions sub PI { my ($parser,$expat,$target,$data)=@_; return $parser->SVG::Parser::Base::PI($target,$data); } # handle XML Comments sub Comment { my ($parser,$expat,$data)=@_; return $parser->SVG::Parser::Base::Comment($data); } # return root SVG document object as result of parse() sub FinishDocument { my ($parser,$expat)=@_; return $parser->SVG::Parser::Base::FinishDocument(); } #--------------------------------------------------------------------------------------- # handle XML declaration, if present sub XMLDecl { my ($parser,$expat,$version,$encoding,$standalone)=@_; return $parser->SVG::Parser::Base::XMLDecl($version,$encoding,$standalone); } # handle Doctype declaration, if present sub Doctype { my ($parser,$expat,$name,$sysid,$pubid,$internal)=@_; return $parser->SVG::Parser::Base::Doctype($name,$sysid,$pubid,$internal); } #--------------------------------------------------------------------------------------- # Unparsed (Expat, Entity, Base, Sysid, Pubid, Notation) sub Unparsed { my ($parser,$expat,$name,$base,$sysid,$pubid,$notation)=@_; return $parser->SVG::Parser::Base::Unparsed($name,$base,$sysid,$pubid,$notation); } # Notation (Expat, Notation, Base, Sysid, Pubid) sub Notation { my ($parser,$expat,$name,$base,$sysid,$pubid)=@_; return $parser->SVG::Parser::Base::Notation($name,$base,$sysid,$pubid); } # Entity (Expat, Name, Val, Sysid, Pubid, Ndata, IsParam) sub Entity { my ($parser,$expat,$name,$val,$sysid,$pubid,$data,$isp)=@_; return $parser->SVG::Parser::Base::Entity($name,$val,$sysid,$pubid,$data,$isp); } # Element (Expat, Name, Model) sub Element { my ($parser,$expat,$name,$model)=@_; return $parser->SVG::Parser::Base::Element($name,$model); } # Attlist (Expat, Elname, Attname, Type, Default, Fixed) sub Attlist { my ($parser,$expat,$name,$attr,$type,$default,$fixed)=@_; return $parser->SVG::Parser::Base::Attlist($name,$attr,$type,$default,$fixed); } #--------------------------------------------------------------------------------------- # SAX -> Expat compatability sub parse_file { shift->parsefile(@_); } #--------------------------------------------------------------------------------------- 1;