← Index
Performance Profile   « block view • line view • sub view »
For t/test-parsing
  Run on Sun Nov 14 09:49:57 2010
Reported on Sun Nov 14 09:50:11 2010

File /usr/share/perl5/XML/SAX/ParserFactory.pm
Statements Executed 64
Total Time 0.0011656 seconds
Subroutines — ordered by exclusive time
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
22117.8ms25.3msXML::SAX::ParserFactory::::parserXML::SAX::ParserFactory::parser
21142µs42µsXML::SAX::ParserFactory::::_parser_classXML::SAX::ParserFactory::_parser_class
11122µs591µsXML::SAX::ParserFactory::::newXML::SAX::ParserFactory::new
11112µs12µsXML::SAX::ParserFactory::::require_featureXML::SAX::ParserFactory::require_feature
LineStmts.Exclusive
Time
Avg.Code
1# $Id: ParserFactory.pm,v 1.13 2002/11/19 18:25:47 matt Exp $
2
3package XML::SAX::ParserFactory;
4
5328µs9µsuse strict;
# spent 8µs making 1 call to strict::import
6339µs13µsuse vars qw($VERSION);
# spent 25µs making 1 call to vars::import
7
81800ns800ns$VERSION = '1.01';
9
10327µs9µsuse Symbol qw(gensym);
# spent 44µs making 1 call to Exporter::import
11336µs12µsuse XML::SAX;
# spent 8µs making 1 call to import
123275µs92µsuse XML::SAX::Exception;
# spent 7µs making 1 call to import
13
14
# spent 591µs (22+568) within XML::SAX::ParserFactory::new which was called # once (22µs+568µs) at line 21 of /usr/share/perl5/MARC/File/XML.pm
sub new {
1511µs1µs my $class = shift;
1612µs2µs my %params = @_; # TODO : Fix this in spec.
1719µs9µs my $self = bless \%params, $class;
18110µs10µs $self->{KnownParsers} = XML::SAX->parsers();
# spent 568µs making 1 call to XML::SAX::parsers
1912µs2µs return $self;
20}
21
22
# spent 25.3ms (17.8+7.50) within XML::SAX::ParserFactory::parser which was called 2 times, avg 12.7ms/call: # once (17.8ms+7.42ms) at line 24 of /usr/share/perl5/MARC/File/XML.pm # once (22µs+77µs) by MARC::File::XML::import at line 32 of /usr/share/perl5/MARC/File/XML.pm
sub parser {
2322µs1µs my $self = shift;
2427µs3µs my @parser_params = @_;
2523µs1µs if (!ref($self)) {
26 $self = $self->new();
27 }
28
29212µs6µs my $parser_class = $self->_parser_class();
# spent 42µs making 2 calls to XML::SAX::ParserFactory::_parser_class, avg 21µs/call
30
3122µs950ns my $version = '';
3224µs2µs if ($parser_class =~ s/\s*\(([\d\.]+)\)\s*$//) {
33 $version = " $1";
34 }
35
36 {
375460µs92µs no strict 'refs';
# spent 35µs making 1 call to strict::unimport
38214µs7µs if (!keys %{"${parser_class}::"}) {
391169µs169µs eval "use $parser_class $version;";
# spent 4µs making 1 call to import
40 }
41 }
42
43220µs10µs return $parser_class->new(@parser_params);
# spent 155µs making 2 calls to XML::SAX::Base::new, avg 77µs/call
44}
45
46
# spent 12µs within XML::SAX::ParserFactory::require_feature which was called # once (12µs+0s) at line 22 of /usr/share/perl5/MARC/File/XML.pm
sub require_feature {
471900ns900ns my $self = shift;
4812µs2µs my ($feature) = @_;
4912µs2µs $self->{RequiredFeatures}{$feature}++;
5011µs1µs return $self;
51}
52
53
# spent 42µs within XML::SAX::ParserFactory::_parser_class which was called 2 times, avg 21µs/call: # 2 times (42µs+0s) by XML::SAX::ParserFactory::parser at line 29, avg 21µs/call
sub _parser_class {
5422µs800ns my $self = shift;
55
56 # First try ParserPackage
5721µs650ns if ($XML::SAX::ParserPackage) {
58 return $XML::SAX::ParserPackage;
59 }
60
61 # Now check if required/preferred is there
6223µs2µs if ($self->{RequiredFeatures}) {
6328µs4µs my %required = %{$self->{RequiredFeatures}};
64 # note - we never go onto the next try (ParserDetails.ini),
65 # because if we can't provide the requested feature
66 # we need to throw an exception.
67 PARSER:
6825µs3µs foreach my $parser (reverse @{$self->{KnownParsers}}) {
6924µs2µs foreach my $feature (keys %required) {
7025µs3µs if (!exists $parser->{Features}{$feature}) {
71 next PARSER;
72 }
73 }
74 # got here - all features must exist!
7527µs3µs return $parser->{Name};
76 }
77 # TODO : should this be NotSupported() ?
78 throw XML::SAX::Exception (
79 Message => "Unable to provide required features",
80 );
81 }
82
83 # Next try SAX.ini
84 for my $dir (@INC) {
85 my $fh = gensym();
86 if (open($fh, "$dir/SAX.ini")) {
87 my $param_list = XML::SAX->_parse_ini_file($fh);
88 my $params = $param_list->[0]->{Features};
89 if ($params->{ParserPackage}) {
90 return $params->{ParserPackage};
91 }
92 else {
93 # we have required features (or nothing?)
94 PARSER:
95 foreach my $parser (reverse @{$self->{KnownParsers}}) {
96 foreach my $feature (keys %$params) {
97 if (!exists $parser->{Features}{$feature}) {
98 next PARSER;
99 }
100 }
101 return $parser->{Name};
102 }
103 XML::SAX->do_warn("Unable to provide SAX.ini required features. Using fallback\n");
104 }
105 last; # stop after first INI found
106 }
107 }
108
109 if (@{$self->{KnownParsers}}) {
110 return $self->{KnownParsers}[-1]{Name};
111 }
112 else {
113 return "XML::SAX::PurePerl"; # backup plan!
114 }
115}
116
11713µs3µs1;
118__END__
119
120=head1 NAME
121
122XML::SAX::ParserFactory - Obtain a SAX parser
123
124=head1 SYNOPSIS
125
126 use XML::SAX::ParserFactory;
127 use XML::SAX::XYZHandler;
128 my $handler = XML::SAX::XYZHandler->new();
129 my $p = XML::SAX::ParserFactory->parser(Handler => $handler);
130 $p->parse_uri("foo.xml");
131 # or $p->parse_string("<foo/>") or $p->parse_file($fh);
132
133=head1 DESCRIPTION
134
135XML::SAX::ParserFactory is a factory class for providing an application
136with a Perl SAX2 XML parser. It is akin to DBI - a front end for other
137parser classes. Each new SAX2 parser installed will register itself
138with XML::SAX, and then it will become available to all applications
139that use XML::SAX::ParserFactory to obtain a SAX parser.
140
141Unlike DBI however, XML/SAX parsers almost all work alike (especially
142if they subclass XML::SAX::Base, as they should), so rather than
143specifying the parser you want in the call to C<parser()>, XML::SAX
144has several ways to automatically choose which parser to use:
145
146=over 4
147
148=item * $XML::SAX::ParserPackage
149
150If this package variable is set, then this package is C<require()>d
151and an instance of this package is returned by calling the C<new()>
152class method in that package. If it cannot be loaded or there is
153an error, an exception will be thrown. The variable can also contain
154a version number:
155
156 $XML::SAX::ParserPackage = "XML::SAX::Expat (0.72)";
157
158And the number will be treated as a minimum version number.
159
160=item * Required features
161
162It is possible to require features from the parsers. For example, you
163may wish for a parser that supports validation via a DTD. To do that,
164use the following code:
165
166 use XML::SAX::ParserFactory;
167 my $factory = XML::SAX::ParserFactory->new();
168 $factory->require_feature('http://xml.org/sax/features/validation');
169 my $parser = $factory->parser(...);
170
171Alternatively, specify the required features in the call to the
172ParserFactory constructor:
173
174 my $factory = XML::SAX::ParserFactory->new(
175 RequiredFeatures => {
176 'http://xml.org/sax/features/validation' => 1,
177 }
178 );
179
180If the features you have asked for are unavailable (for example the
181user might not have a validating parser installed), then an
182exception will be thrown.
183
184The list of known parsers is searched in reverse order, so it will
185always return the last installed parser that supports all of your
186requested features (Note: this is subject to change if someone
187comes up with a better way of making this work).
188
189=item * SAX.ini
190
191ParserFactory will search @INC for a file called SAX.ini, which
192is in a simple format:
193
194 # a comment looks like this,
195 ; or like this, and are stripped anywhere in the file
196 key = value # SAX.in contains key/value pairs.
197
198All whitespace is non-significant.
199
200This file can contain either a line:
201
202 ParserPackage = MyParserModule (1.02)
203
204Where MyParserModule is the module to load and use for the parser,
205and the number in brackets is a minimum version to load.
206
207Or you can list required features:
208
209 http://xml.org/sax/features/validation = 1
210
211And each feature with a true value will be required.
212
213=item * Fallback
214
215If none of the above works, the last parser installed on the user's
216system will be used. The XML::SAX package ships with a pure perl
217XML parser, XML::SAX::PurePerl, so that there will always be a
218fallback parser.
219
220=back
221
222=head1 AUTHOR
223
224Matt Sergeant, matt@sergeant.org
225
226=head1 LICENSE
227
228This is free software, you may use it and distribute it under the same
229terms as Perl itself.
230
231=cut
232