expat.pm

来自「one of the linux gd libraries」· PM 代码 · 共 1,231 行 · 第 1/3 页

PM
1,231
字号
      }    }  }  $text;}sub skip_until {  my $self = shift;  if ($self->{_State_} <= 1) {    SkipUntil($self->{Parser}, $_[0]);  }}sub release {  my $self = shift;  ParserRelease($self->{Parser});}sub DESTROY {  my $self = shift;  ParserFree($self->{Parser});}sub parse {  my $self = shift;  my $arg = shift;  croak "Parse already in progress (Expat)" if $self->{_State_};  $self->{_State_} = 1;  my $parser = $self->{Parser};  my $ioref;  my $result = 0;    if (defined $arg) {    if (ref($arg) and UNIVERSAL::isa($arg, 'IO::Handle')) {      $ioref = $arg;    } elsif (tied($arg)) {      my $class = ref($arg);      no strict 'refs';      $ioref = $arg if defined &{"${class}::TIEHANDLE"};    }    else {      require IO::Handle;      eval {        no strict 'refs';        $ioref = *{$arg}{IO} if defined *{$arg};      };      undef $@;    }  }    if (defined($ioref)) {    my $delim = $self->{Stream_Delimiter};    my $prev_rs;        $prev_rs = ref($ioref)->input_record_separator("\n$delim\n")      if defined($delim);        $result = ParseStream($parser, $ioref, $delim);        ref($ioref)->input_record_separator($prev_rs)      if defined($delim);  } else {    $result = ParseString($parser, $arg);  }    $self->{_State_} = 2;  $result or croak $self->{ErrorMessage};}sub parsestring {  my $self = shift;  $self->parse(@_);}sub parsefile {  my $self = shift;  croak "Parser has already been used" if $self->{_State_};  local(*FILE);  open(FILE, $_[0]) or  croak "Couldn't open $_[0]:\n$!";  binmode(FILE);  my $ret = $self->parse(*FILE);  close(FILE);  $ret;}################################################################package XML::Parser::ContentModel;use overload '""' => \&asString, 'eq' => \&thiseq;sub EMPTY  () {1}sub ANY    () {2}sub MIXED  () {3}sub NAME   () {4}sub CHOICE () {5}sub SEQ    () {6}sub isempty {  return $_[0]->{Type} == EMPTY;}sub isany {  return $_[0]->{Type} == ANY;}sub ismixed {  return $_[0]->{Type} == MIXED;}sub isname {  return $_[0]->{Type} == NAME;}sub name {  return $_[0]->{Tag};}sub ischoice {  return $_[0]->{Type} == CHOICE;}sub isseq {  return $_[0]->{Type} == SEQ;}sub quant {  return $_[0]->{Quant};}sub children {  my $children = $_[0]->{Children};  if (defined $children) {    return @$children;  }  return undef;}sub asString {  my ($self) = @_;  my $ret;  if ($self->{Type} == NAME) {    $ret = $self->{Tag};  }  elsif ($self->{Type} == EMPTY) {    return "EMPTY";  }  elsif ($self->{Type} == ANY) {    return "ANY";  }  elsif ($self->{Type} == MIXED) {    $ret = '(#PCDATA';    foreach (@{$self->{Children}}) {      $ret .= '|' . $_;    }    $ret .= ')';  }  else {    my $sep = $self->{Type} == CHOICE ? '|' : ',';    $ret = '(' . join($sep, map { $_->asString } @{$self->{Children}}) . ')';  }  $ret .= $self->{Quant} if $self->{Quant};  return $ret;}sub thiseq {  my $self = shift;  return $self->asString eq $_[0];}################################################################package XML::Parser::ExpatNB;use vars qw(@ISA);use Carp;@ISA = qw(XML::Parser::Expat);sub parse {  my $self = shift;  my $class = ref($self);  croak "parse method not supported in $class";}sub parsestring {  my $self = shift;  my $class = ref($self);  croak "parsestring method not supported in $class";}sub parsefile {  my $self = shift;  my $class = ref($self);  croak "parsefile method not supported in $class";}sub parse_more {  my ($self, $data) = @_;  $self->{_State_} = 1;  my $ret = XML::Parser::Expat::ParsePartial($self->{Parser}, $data);  croak $self->{ErrorMessage} unless $ret;}sub parse_done {  my $self = shift;  my $ret = XML::Parser::Expat::ParseDone($self->{Parser});  unless ($ret) {    my $msg = $self->{ErrorMessage};    $self->release;    croak $msg;  }  $self->{_State_} = 2;  my $result = $ret;  my @result = ();  my $final = $self->{FinalHandler};  if (defined $final) {    if (wantarray) {      @result = &$final($self);    }    else {      $result = &$final($self);    }  }  $self->release;  return unless defined wantarray;  return wantarray ? @result : $result;}################################################################package XML::Parser::Encinfo;sub DESTROY {  my $self = shift;  XML::Parser::Expat::FreeEncoding($self);}1;__END__=head1 NAMEXML::Parser::Expat - Lowlevel access to James Clark's expat XML parser=head1 SYNOPSIS use XML::Parser::Expat; $parser = new XML::Parser::Expat; $parser->setHandlers('Start' => \&sh,                      'End'   => \&eh,                      'Char'  => \&ch); open(FOO, 'info.xml') or die "Couldn't open"; $parser->parse(*FOO); close(FOO); # $parser->parse('<foo id="me"> here <em>we</em> go </foo>'); sub sh {   my ($p, $el, %atts) = @_;   $p->setHandlers('Char' => \&spec)     if ($el eq 'special');   ... } sub eh {   my ($p, $el) = @_;   $p->setHandlers('Char' => \&ch)  # Special elements won't contain     if ($el eq 'special');         # other special elements   ... } =head1 DESCRIPTIONThis module provides an interface to James Clark's XML parser, expat. As inexpat, a single instance of the parser can only parse one document. Callsto parsestring after the first for a given instance will die.Expat (and XML::Parser::Expat) are event based. As the parser recognizesparts of the document (say the start or end of an XML element), then anyhandlers registered for that type of an event are called with suitableparameters.=head1 METHODS=over 4=item newThis is a class method, the constructor for XML::Parser::Expat. Options arepassed as keyword value pairs. The recognized options are:=over 4=item * ProtocolEncodingThe protocol encoding name. The default is none. The expat built-inencodings are: C<UTF-8>, C<ISO-8859-1>, C<UTF-16>, and C<US-ASCII>.Other encodings may be used if they have encoding maps in one of thedirectories in the @Encoding_Path list. Setting the protocol encodingoverrides any encoding in the XML declaration.=item * NamespacesWhen this option is given with a true value, then the parser does namespaceprocessing. By default, namespace processing is turned off. When it isturned on, the parser consumes I<xmlns> attributes and strips off prefixesfrom element and attributes names where those prefixes have a definednamespace. A name's namespace can be found using the L<"namespace"> methodand two names can be checked for absolute equality with the L<"eq_name">method.=item * NoExpandNormally, the parser will try to expand references to entities defined inthe internal subset. If this option is set to a true value, and a defaulthandler is also set, then the default handler will be called when anentity reference is seen in text. This has no effect if a default handlerhas not been registered, and it has no effect on the expansion of entityreferences inside attribute values.=item * Stream_DelimiterThis option takes a string value. When this string is found alone on a linewhile parsing from a stream, then the parse is ended as if it saw an end offile. The intended use is with a stream of xml documents in a MIME multipartformat. The string should not contain a trailing newline.=item * ErrorContextWhen this option is defined, errors are reported in context. The valueof ErrorContext should be the number of lines to show on either side ofthe line in which the error occurred.=item * ParseParamEntUnless standalone is set to "yes" in the XML declaration, setting this toa true value allows the external DTD to be read, and parameter entitiesto be parsed and expanded.=item * BaseThe base to use for relative pathnames or URLs. This can also be done byusing the base method.=back=item setHandlers(TYPE, HANDLER [, TYPE, HANDLER [...]])This method registers handlers for the various events. If no handlers areregistered, then a call to parsestring or parsefile will only determine ifthe corresponding XML document is well formed (by returning without error.)This may be called from within a handler, after the parse has started.Setting a handler to something that evaluates to false unsets thathandler.This method returns a list of type, handler pairs corresponding to theinput. The handlers returned are the ones that were in effect before thecall to setHandlers.The recognized events and the parameters passed to the correspondinghandlers are:=over 4=item * Start             (Parser, Element [, Attr, Val [,...]])This event is generated when an XML start tag is recognized. Parser isan XML::Parser::Expat instance. Element is the name of the XML element thatis opened with the start tag. The Attr & Val pairs are generated for eachattribute in the start tag.=item * End               (Parser, Element)This event is generated when an XML end tag is recognized. Note thatan XML empty tag (<foo/>) generates both a start and an end event.There is always a lower level start and end handler installed that wrapthe corresponding callbacks. This is to handle the context mechanism.A consequence of this is that the default handler (see below) will notsee a start tag or end tag unless the default_current method is called.=item * Char              (Parser, String)This event is generated when non-markup is recognized. The non-markupsequence of characters is in String. A single non-markup sequence ofcharacters may generate multiple calls to this handler. Whatever theencoding of the string in the original document, this is given to thehandler in UTF-8.=item * Proc              (Parser, Target, Data)This event is generated when a processing instruction is recognized.=item * Comment           (Parser, String)This event is generated when a comment is recognized.=item * CdataStart        (Parser)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?