Profile of /usr/local/lib/perl5/site_perl/5.10.1/XML/SAX/ParserFactory.pm

← Index
NYTProf Performance Profile «block view•line view•sub view»
For 05.Domain_and_Item.t
Run on Tue May 4 16:57:28 2010
Reported on Tue May 4 16:58:33 2010

File | /usr/local/lib/perl5/site_perl/5.10.1/XML/SAX/ParserFactory.pm
Statements Executed | 1332
Statement Execution Time | 23.7ms

Subroutines — ordered by exclusive time
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
1 | 1 | 1 | 42.7ms | 42.9ms | XML::SAX::ParserFactory::::BEGIN@12XML::SAX::ParserFactory::BEGIN@12
287 | 1 | 2 | 15.0ms | 15.0ms | XML::SAX::ParserFactory::::CORE:openXML::SAX::ParserFactory::CORE:open (opcode)
41 | 1 | 1 | 3.13ms | 20.1ms | XML::SAX::ParserFactory::::_parser_classXML::SAX::ParserFactory::_parser_class
41 | 1 | 1 | 2.36ms | 304ms | XML::SAX::ParserFactory::::parserXML::SAX::ParserFactory::parser
41 | 1 | 1 | 635µs | 11.2ms | XML::SAX::ParserFactory::::newXML::SAX::ParserFactory::new
41 | 1 | 2 | 44µs | 44µs | XML::SAX::ParserFactory::::CORE:substXML::SAX::ParserFactory::CORE:subst (opcode)
1 | 1 | 1 | 21µs | 24µs | XML::SAX::ParserFactory::::BEGIN@5XML::SAX::ParserFactory::BEGIN@5
1 | 1 | 1 | 11µs | 42µs | XML::SAX::ParserFactory::::BEGIN@10XML::SAX::ParserFactory::BEGIN@10
1 | 1 | 1 | 10µs | 10µs | XML::SAX::ParserFactory::::BEGIN@11XML::SAX::ParserFactory::BEGIN@11
1 | 1 | 1 | 9µs | 41µs | XML::SAX::ParserFactory::::BEGIN@6XML::SAX::ParserFactory::BEGIN@6
0 | 0 | 0 | 0s | 0s | XML::SAX::ParserFactory::::require_featureXML::SAX::ParserFactory::require_feature

Call graph for these subroutines as a Graphviz dot language file.

Line | State ments | Time on line | Calls | Time in subs | Code
--- | --- | --- | --- | --- | ---
1 |  |  |  |  | # $Id: ParserFactory.pm,v 1.14 2008-08-04 04:51:29 grant Exp $
2 |  |  |  |  |
3 |  |  |  |  | package XML::SAX::ParserFactory;
4 |  |  |  |  |
5 | 3 | 32µs | 2 | 28µs | # spent 24µs (21+4) within XML::SAX::ParserFactory::BEGIN@5 which was called # once (21µs+4µs) by XML::SAX::BEGIN@18 at line 5 use strict; # spent 24µs making 1 call to XML::SAX::ParserFactory::BEGIN@5 # spent 4µs making 1 call to strict::import
6 | 3 | 39µs | 2 | 74µs | # spent 41µs (9+33) within XML::SAX::ParserFactory::BEGIN@6 which was called # once (9µs+33µs) by XML::SAX::BEGIN@18 at line 6 use vars qw($VERSION); # spent 41µs making 1 call to XML::SAX::ParserFactory::BEGIN@6 # spent 33µs making 1 call to vars::import
7 |  |  |  |  |
8 | 1 | 3µs |  |  | $VERSION = '1.01';
9 |  |  |  |  |
10 | 3 | 30µs | 2 | 73µs | # spent 42µs (11+31) within XML::SAX::ParserFactory::BEGIN@10 which was called # once (11µs+31µs) by XML::SAX::BEGIN@18 at line 10 use Symbol qw(gensym); # spent 42µs making 1 call to XML::SAX::ParserFactory::BEGIN@10 # spent 31µs making 1 call to Exporter::import
11 | 3 | 41µs | 1 | 10µs | # spent 10µs within XML::SAX::ParserFactory::BEGIN@11 which was called # once (10µs+0s) by XML::SAX::BEGIN@18 at line 11 use XML::SAX; # spent 10µs making 1 call to XML::SAX::ParserFactory::BEGIN@11
12 | 3 | 3.28ms | 1 | 42.9ms | # spent 42.9ms (42.7+213µs) within XML::SAX::ParserFactory::BEGIN@12 which was called # once (42.7ms+213µs) by XML::SAX::BEGIN@18 at line 12 use XML::SAX::Exception; # spent 42.9ms making 1 call to XML::SAX::ParserFactory::BEGIN@12
13 |  |  |  |  |
14 |  |  |  |  | # spent 11.2ms (635µs+10.6) within XML::SAX::ParserFactory::new which was called 41 times, avg 273µs/call: # 41 times (635µs+10.6ms) by XML::SAX::ParserFactory::parser at line 25, avg 273µs/call sub new {
15 | 205 | 564µs |  |  | my $class = shift;
16 |  |  |  |  | my %params = @_; # TODO : Fix this in spec.
17 |  |  |  |  | my $self = bless \%params, $class;
18 |  |  |  |  | $self->{KnownParsers} = XML::SAX->parsers(); # spent 10.6ms making 41 calls to XML::SAX::parsers, avg 257µs/call
19 |  |  |  |  | return $self;
20 |  |  |  |  | }
21 |  |  |  |  |
22 |  |  |  |  | # spent 304ms (2.36+302) within XML::SAX::ParserFactory::parser which was called 41 times, avg 7.41ms/call: # 41 times (2.36ms+302ms) by XML::Simple::build_tree at line 358 of XML/Simple.pm, avg 7.41ms/call sub parser {
23 | 328 | 1.61ms |  |  | my $self = shift;
24 |  |  |  |  | my @parser_params = @_;
25 |  |  |  |  | if (!ref($self)) { # spent 11.2ms making 41 calls to XML::SAX::ParserFactory::new, avg 273µs/call
26 |  |  |  |  | $self = $self->new();
27 |  |  |  |  | }
28 |  |  |  |  |
29 |  |  |  |  | my $parser_class = $self->_parser_class(); # spent 20.1ms making 41 calls to XML::SAX::ParserFactory::_parser_class, avg 490µs/call
30 |  |  |  |  |
31 |  |  |  |  | my $version = '';
32 |  |  |  |  | if ($parser_class =~ s/\s*\(([\d\.]+)\)\s*$//) { # spent 44µs making 41 calls to XML::SAX::ParserFactory::CORE:subst, avg 1µs/call
33 |  |  |  |  | $version = " $1";
34 |  |  |  |  | }
35 |  |  |  |  |
36 | 2 | 65µs | 41 | 144µs | if (!$parser_class->can('new')) { # spent 144µs making 41 calls to UNIVERSAL::can, avg 4µs/call
37 | 1 | 280µs |  |  | eval "require $parser_class $version;";
38 |  |  |  |  | die $@ if $@;
39 |  |  |  |  | }
40 |  |  |  |  |
41 |  |  |  |  | return $parser_class->new(@parser_params); # spent 2.87ms making 41 calls to XML::SAX::Base::new, avg 70µs/call
42 |  |  |  |  | }
43 |  |  |  |  |
44 |  |  |  |  | sub require_feature {
45 |  |  |  |  | my $self = shift;
46 |  |  |  |  | my ($feature) = @_;
47 |  |  |  |  | $self->{RequiredFeatures}{$feature}++;
48 |  |  |  |  | return $self;
49 |  |  |  |  | }
50 |  |  |  |  |
51 |  |  |  |  | # spent 20.1ms (3.13+16.9) within XML::SAX::ParserFactory::_parser_class which was called 41 times, avg 490µs/call: # 41 times (3.13ms+16.9ms) by XML::SAX::ParserFactory::parser at line 29, avg 490µs/call sub _parser_class {
52 | 205 | 513µs |  |  | my $self = shift;
53 |  |  |  |  |
54 |  |  |  |  | # First try ParserPackage
55 |  |  |  |  | if ($XML::SAX::ParserPackage) {
56 |  |  |  |  | return $XML::SAX::ParserPackage;
57 |  |  |  |  | }
58 |  |  |  |  |
59 |  |  |  |  | # Now check if required/preferred is there
60 |  |  |  |  | if ($self->{RequiredFeatures}) {
61 |  |  |  |  | my %required = %{$self->{RequiredFeatures}};
62 |  |  |  |  | # note - we never go onto the next try (ParserDetails.ini),
63 |  |  |  |  | # because if we can't provide the requested feature
64 |  |  |  |  | # we need to throw an exception.
65 |  |  |  |  | PARSER:
66 |  |  |  |  | foreach my $parser (reverse @{$self->{KnownParsers}}) {
67 |  |  |  |  | foreach my $feature (keys %required) {
68 |  |  |  |  | if (!exists $parser->{Features}{$feature}) {
69 |  |  |  |  | next PARSER;
70 |  |  |  |  | }
71 |  |  |  |  | }
72 |  |  |  |  | # got here - all features must exist!
73 |  |  |  |  | return $parser->{Name};
74 |  |  |  |  | }
75 |  |  |  |  | # TODO : should this be NotSupported() ?
76 |  |  |  |  | throw XML::SAX::Exception (
77 |  |  |  |  | Message => "Unable to provide required features",
78 |  |  |  |  | );
79 |  |  |  |  | }
80 |  |  |  |  |
81 |  |  |  |  | # Next try SAX.ini
82 |  |  |  |  | for my $dir (@INC) {
83 | 574 | 17.2ms | 287 | 1.96ms | my $fh = gensym(); # spent 1.96ms making 287 calls to Symbol::gensym, avg 7µs/call
84 |  |  |  |  | if (open($fh, "$dir/SAX.ini")) { # spent 15.0ms making 287 calls to XML::SAX::ParserFactory::CORE:open, avg 52µs/call
85 |  |  |  |  | my $param_list = XML::SAX->_parse_ini_file($fh);
86 |  |  |  |  | my $params = $param_list->[0]->{Features};
87 |  |  |  |  | if ($params->{ParserPackage}) {
88 |  |  |  |  | return $params->{ParserPackage};
89 |  |  |  |  | }
90 |  |  |  |  | else {
91 |  |  |  |  | # we have required features (or nothing?)
92 |  |  |  |  | PARSER:
93 |  |  |  |  | foreach my $parser (reverse @{$self->{KnownParsers}}) {
94 |  |  |  |  | foreach my $feature (keys %$params) {
95 |  |  |  |  | if (!exists $parser->{Features}{$feature}) {
96 |  |  |  |  | next PARSER;
97 |  |  |  |  | }
98 |  |  |  |  | }
99 |  |  |  |  | return $parser->{Name};
100 |  |  |  |  | }
101 |  |  |  |  | XML::SAX->do_warn("Unable to provide SAX.ini required features. Using fallback\n");
102 |  |  |  |  | }
103 |  |  |  |  | last; # stop after first INI found
104 |  |  |  |  | }
105 |  |  |  |  | }
106 |  |  |  |  |
107 |  |  |  |  | if (@{$self->{KnownParsers}}) {
108 |  |  |  |  | return $self->{KnownParsers}[-1]{Name};
109 |  |  |  |  | }
110 |  |  |  |  | else {
111 |  |  |  |  | return "XML::SAX::PurePerl"; # backup plan!
112 |  |  |  |  | }
113 |  |  |  |  | }
114 |  |  |  |  |
115 | 1 | 23µs |  |  | 1;
116 |  |  |  |  | __END__
117 |  |  |  |  |
118 |  |  |  |  | =head1 NAME
119 |  |  |  |  |
120 |  |  |  |  | XML::SAX::ParserFactory - Obtain a SAX parser
121 |  |  |  |  |
122 |  |  |  |  | =head1 SYNOPSIS
123 |  |  |  |  |
124 |  |  |  |  | use XML::SAX::ParserFactory;
125 |  |  |  |  | use XML::SAX::XYZHandler;
126 |  |  |  |  | my $handler = XML::SAX::XYZHandler->new();
127 |  |  |  |  | my $p = XML::SAX::ParserFactory->parser(Handler => $handler);
128 |  |  |  |  | $p->parse_uri("foo.xml");
129 |  |  |  |  | # or $p->parse_string("<foo/>") or $p->parse_file($fh);
130 |  |  |  |  |
131 |  |  |  |  | =head1 DESCRIPTION
132 |  |  |  |  |
133 |  |  |  |  | XML::SAX::ParserFactory is a factory class for providing an application
134 |  |  |  |  | with a Perl SAX2 XML parser. It is akin to DBI - a front end for other
135 |  |  |  |  | parser classes. Each new SAX2 parser installed will register itself
136 |  |  |  |  | with XML::SAX, and then it will become available to all applications
137 |  |  |  |  | that use XML::SAX::ParserFactory to obtain a SAX parser.
138 |  |  |  |  |
139 |  |  |  |  | Unlike DBI however, XML/SAX parsers almost all work alike (especially
140 |  |  |  |  | if they subclass XML::SAX::Base, as they should), so rather than
141 |  |  |  |  | specifying the parser you want in the call to C<parser()>, XML::SAX
142 |  |  |  |  | has several ways to automatically choose which parser to use:
143 |  |  |  |  |
144 |  |  |  |  | =over 4
145 |  |  |  |  |
146 |  |  |  |  | =item * $XML::SAX::ParserPackage
147 |  |  |  |  |
148 |  |  |  |  | If this package variable is set, then this package is C<require()>d
149 |  |  |  |  | and an instance of this package is returned by calling the C<new()>
150 |  |  |  |  | class method in that package. If it cannot be loaded or there is
151 |  |  |  |  | an error, an exception will be thrown. The variable can also contain
152 |  |  |  |  | a version number:
153 |  |  |  |  |
154 |  |  |  |  | $XML::SAX::ParserPackage = "XML::SAX::Expat (0.72)";
155 |  |  |  |  |
156 |  |  |  |  | And the number will be treated as a minimum version number.
157 |  |  |  |  |
158 |  |  |  |  | =item * Required features
159 |  |  |  |  |
160 |  |  |  |  | It is possible to require features from the parsers. For example, you
161 |  |  |  |  | may wish for a parser that supports validation via a DTD. To do that,
162 |  |  |  |  | use the following code:
163 |  |  |  |  |
164 |  |  |  |  | use XML::SAX::ParserFactory;
165 |  |  |  |  | my $factory = XML::SAX::ParserFactory->new();
166 |  |  |  |  | $factory->require_feature('http://xml.org/sax/features/validation');
167 |  |  |  |  | my $parser = $factory->parser(...);
168 |  |  |  |  |
169 |  |  |  |  | Alternatively, specify the required features in the call to the
170 |  |  |  |  | ParserFactory constructor:
171 |  |  |  |  |
172 |  |  |  |  | my $factory = XML::SAX::ParserFactory->new(
173 |  |  |  |  | RequiredFeatures => {
174 |  |  |  |  | 'http://xml.org/sax/features/validation' => 1,
175 |  |  |  |  | }
176 |  |  |  |  | );
177 |  |  |  |  |
178 |  |  |  |  | If the features you have asked for are unavailable (for example the
179 |  |  |  |  | user might not have a validating parser installed), then an
180 |  |  |  |  | exception will be thrown.
181 |  |  |  |  |
182 |  |  |  |  | The list of known parsers is searched in reverse order, so it will
183 |  |  |  |  | always return the last installed parser that supports all of your
184 |  |  |  |  | requested features (Note: this is subject to change if someone
185 |  |  |  |  | comes up with a better way of making this work).
186 |  |  |  |  |
187 |  |  |  |  | =item * SAX.ini
188 |  |  |  |  |
189 |  |  |  |  | ParserFactory will search @INC for a file called SAX.ini, which
190 |  |  |  |  | is in a simple format:
191 |  |  |  |  |
192 |  |  |  |  | # a comment looks like this,
193 |  |  |  |  | ; or like this, and are stripped anywhere in the file
194 |  |  |  |  | key = value # SAX.in contains key/value pairs.
195 |  |  |  |  |
196 |  |  |  |  | All whitespace is non-significant.
197 |  |  |  |  |
198 |  |  |  |  | This file can contain either a line:
199 |  |  |  |  |
200 |  |  |  |  | ParserPackage = MyParserModule (1.02)
201 |  |  |  |  |
202 |  |  |  |  | Where MyParserModule is the module to load and use for the parser,
203 |  |  |  |  | and the number in brackets is a minimum version to load.
204 |  |  |  |  |
205 |  |  |  |  | Or you can list required features:
206 |  |  |  |  |
207 |  |  |  |  | http://xml.org/sax/features/validation = 1
208 |  |  |  |  |
209 |  |  |  |  | And each feature with a true value will be required.
210 |  |  |  |  |
211 |  |  |  |  | =item * Fallback
212 |  |  |  |  |
213 |  |  |  |  | If none of the above works, the last parser installed on the user's
214 |  |  |  |  | system will be used. The XML::SAX package ships with a pure perl
215 |  |  |  |  | XML parser, XML::SAX::PurePerl, so that there will always be a
216 |  |  |  |  | fallback parser.
217 |  |  |  |  |
218 |  |  |  |  | =back
219 |  |  |  |  |
220 |  |  |  |  | =head1 AUTHOR
221 |  |  |  |  |
222 |  |  |  |  | Matt Sergeant, matt@sergeant.org
223 |  |  |  |  |
224 |  |  |  |  | =head1 LICENSE
225 |  |  |  |  |
226 |  |  |  |  | This is free software, you may use it and distribute it under the same
227 |  |  |  |  | terms as Perl itself.
228 |  |  |  |  |
229 |  |  |  |  | =cut
230 |  |  |  |  |
|  |  |  |  | # spent 15.0ms within XML::SAX::ParserFactory::CORE:open which was called 287 times, avg 52µs/call: # 287 times (15.0ms+0s) by XML::SAX::ParserFactory::_parser_class at line 84 of XML/SAX/ParserFactory.pm, avg 52µs/call sub XML::SAX::ParserFactory::CORE:open; # xsub
|  |  |  |  | # spent 44µs within XML::SAX::ParserFactory::CORE:subst which was called 41 times, avg 1µs/call: # 41 times (44µs+0s) by XML::SAX::ParserFactory::parser at line 32 of XML/SAX/ParserFactory.pm, avg 1µs/call sub XML::SAX::ParserFactory::CORE:subst; # xsub