Filename | /usr/lib64/perl5/vendor_perl/5.16.0/x86_64-linux/XML/LibXML.pm |
Statements | Executed 316 statements in 91.0ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
2 | 1 | 1 | 56.9ms | 132ms | _parse_sax_string (xsub) | XML::LibXML::
1 | 1 | 1 | 12.0ms | 76.1ms | BEGIN@24 | XML::LibXML::
1 | 1 | 1 | 4.59ms | 5.69ms | BEGIN@26 | XML::LibXML::
1 | 1 | 1 | 4.29ms | 15.8ms | BEGIN@25 | XML::LibXML::
1 | 1 | 1 | 4.06ms | 4.06ms | bootstrap (xsub) | XML::LibXML::
2 | 1 | 1 | 344µs | 133ms | parse_string | XML::LibXML::
3 | 3 | 2 | 330µs | 4.87ms | import | XML::LibXML::
2 | 1 | 1 | 319µs | 492µs | init_callbacks | XML::LibXML::InputCallback::
1 | 1 | 1 | 316µs | 27.3ms | BEGIN@29 | XML::LibXML::
2 | 1 | 1 | 157µs | 729µs | _init_callbacks | XML::LibXML::
4 | 2 | 1 | 128µs | 128µs | set_handler | XML::LibXML::
2 | 1 | 1 | 104µs | 132µs | cleanup_callbacks | XML::LibXML::InputCallback::
1 | 1 | 1 | 103µs | 2.23ms | BEGIN@235 | XML::LibXML::
2 | 1 | 1 | 95µs | 95µs | new | XML::LibXML::
2 | 1 | 1 | 80µs | 80µs | new | XML::LibXML::InputCallback::
1 | 1 | 1 | 78µs | 176µs | BEGIN@13 | XML::LibXML::
1 | 1 | 1 | 76µs | 226µs | BEGIN@1715 | XML::LibXML::Comment::
1 | 1 | 1 | 76µs | 206µs | BEGIN@1753 | XML::LibXML::Dtd::
1 | 1 | 1 | 68µs | 256µs | BEGIN@1366 | XML::LibXML::Document::
1 | 1 | 1 | 68µs | 191µs | BEGIN@1722 | XML::LibXML::CDATASection::
1 | 1 | 1 | 65µs | 248µs | BEGIN@1670 | XML::LibXML::Text::
1 | 1 | 1 | 64µs | 187µs | BEGIN@1731 | XML::LibXML::Attr::
1 | 1 | 1 | 64µs | 313µs | BEGIN@1488 | XML::LibXML::Element::
1 | 1 | 1 | 64µs | 176µs | BEGIN@27 | XML::LibXML::
2 | 1 | 1 | 63µs | 194µs | _cleanup_callbacks | XML::LibXML::
1 | 1 | 1 | 63µs | 1.43ms | BEGIN@1830 | XML::LibXML::NamedNodeMap::
1 | 1 | 1 | 63µs | 184µs | BEGIN@1764 | XML::LibXML::PI::
1 | 1 | 1 | 62µs | 533µs | BEGIN@2076 | XML::LibXML::InputCallback::
1 | 1 | 1 | 61µs | 299µs | BEGIN@160 | XML::LibXML::
1 | 1 | 1 | 60µs | 218µs | BEGIN@1462 | XML::LibXML::DocumentFragment::
1 | 1 | 1 | 58µs | 194µs | BEGIN@1485 | XML::LibXML::Element::
1 | 1 | 1 | 57µs | 226µs | BEGIN@166 | XML::LibXML::
1 | 1 | 1 | 56µs | 299µs | BEGIN@19 | XML::LibXML::
1 | 1 | 1 | 54µs | 442µs | BEGIN@36 | XML::LibXML::
1 | 1 | 1 | 54µs | 2.39ms | BEGIN@1487 | XML::LibXML::Element::
1 | 1 | 1 | 54µs | 1.28ms | BEGIN@14 | XML::LibXML::
1 | 1 | 1 | 51µs | 258µs | BEGIN@22 | XML::LibXML::
1 | 1 | 1 | 51µs | 51µs | END (xsub) | XML::LibXML::
1 | 1 | 1 | 50µs | 272µs | BEGIN@21 | XML::LibXML::
1 | 1 | 1 | 49µs | 231µs | BEGIN@161 | XML::LibXML::
1 | 1 | 1 | 49µs | 217µs | BEGIN@177 | XML::LibXML::
1 | 1 | 1 | 48µs | 210µs | BEGIN@163 | XML::LibXML::
1 | 1 | 1 | 48µs | 247µs | BEGIN@175 | XML::LibXML::
1 | 1 | 1 | 47µs | 253µs | BEGIN@164 | XML::LibXML::
1 | 1 | 1 | 47µs | 207µs | BEGIN@171 | XML::LibXML::
1 | 1 | 1 | 47µs | 233µs | BEGIN@172 | XML::LibXML::
1 | 1 | 1 | 47µs | 211µs | BEGIN@178 | XML::LibXML::
1 | 1 | 1 | 47µs | 219µs | BEGIN@179 | XML::LibXML::
1 | 1 | 1 | 47µs | 219µs | BEGIN@176 | XML::LibXML::
1 | 1 | 1 | 46µs | 207µs | BEGIN@170 | XML::LibXML::
1 | 1 | 1 | 46µs | 213µs | BEGIN@162 | XML::LibXML::
1 | 1 | 1 | 46µs | 207µs | BEGIN@168 | XML::LibXML::
1 | 1 | 1 | 46µs | 207µs | BEGIN@169 | XML::LibXML::
1 | 1 | 1 | 46µs | 219µs | BEGIN@165 | XML::LibXML::
1 | 1 | 1 | 45µs | 210µs | BEGIN@167 | XML::LibXML::
1 | 1 | 1 | 45µs | 211µs | BEGIN@173 | XML::LibXML::
1 | 1 | 1 | 45µs | 211µs | BEGIN@174 | XML::LibXML::
1 | 1 | 1 | 44µs | 44µs | BEGIN@1932 | XML::LibXML::_SAXParser::
2 | 1 | 1 | 38µs | 38µs | match_callback | XML::LibXML::
2 | 1 | 1 | 35µs | 35µs | read_callback | XML::LibXML::
2 | 1 | 1 | 34µs | 34µs | open_callback | XML::LibXML::
2 | 1 | 1 | 33µs | 33µs | close_callback | XML::LibXML::
2 | 1 | 1 | 33µs | 33µs | lib_init_callbacks (xsub) | XML::LibXML::InputCallback::
1 | 1 | 1 | 32µs | 32µs | BEGIN@2078 | XML::LibXML::InputCallback::
1 | 1 | 1 | 31µs | 31µs | LIBXML_RUNTIME_VERSION (xsub) | XML::LibXML::
7 | 3 | 1 | 30µs | 30µs | CORE:match (opcode) | XML::LibXML::
2 | 1 | 1 | 28µs | 28µs | lib_cleanup_callbacks (xsub) | XML::LibXML::InputCallback::
1 | 1 | 1 | 15µs | 15µs | LIBXML_VERSION (xsub) | XML::LibXML::
0 | 0 | 0 | 0s | 0s | setNamespace | XML::LibXML::Attr::
0 | 0 | 0 | 0s | 0s | CLONE | XML::LibXML::
0 | 0 | 0 | 0s | 0s | CLONE_SKIP | XML::LibXML::
0 | 0 | 0 | 0s | 0s | actualEncoding | XML::LibXML::Document::
0 | 0 | 0 | 0s | 0s | insertPI | XML::LibXML::Document::
0 | 0 | 0 | 0s | 0s | insertProcessingInstruction | XML::LibXML::Document::
0 | 0 | 0 | 0s | 0s | process_xinclude | XML::LibXML::Document::
0 | 0 | 0 | 0s | 0s | serialize | XML::LibXML::Document::
0 | 0 | 0 | 0s | 0s | setDocumentElement | XML::LibXML::Document::
0 | 0 | 0 | 0s | 0s | toString | XML::LibXML::Document::
0 | 0 | 0 | 0s | 0s | toString | XML::LibXML::DocumentFragment::
0 | 0 | 0 | 0s | 0s | appendWellBalancedChunk | XML::LibXML::Element::
0 | 0 | 0 | 0s | 0s | getAttribute | XML::LibXML::Element::
0 | 0 | 0 | 0s | 0s | getAttributeNS | XML::LibXML::Element::
0 | 0 | 0 | 0s | 0s | getChildrenByLocalName | XML::LibXML::Element::
0 | 0 | 0 | 0s | 0s | getChildrenByTagName | XML::LibXML::Element::
0 | 0 | 0 | 0s | 0s | getChildrenByTagNameNS | XML::LibXML::Element::
0 | 0 | 0 | 0s | 0s | getElementsByLocalName | XML::LibXML::Element::
0 | 0 | 0 | 0s | 0s | getElementsByTagName | XML::LibXML::Element::
0 | 0 | 0 | 0s | 0s | getElementsByTagNameNS | XML::LibXML::Element::
0 | 0 | 0 | 0s | 0s | setAttribute | XML::LibXML::Element::
0 | 0 | 0 | 0s | 0s | setAttributeNS | XML::LibXML::Element::
0 | 0 | 0 | 0s | 0s | setNamespace | XML::LibXML::Element::
0 | 0 | 0 | 0s | 0s | CLONE_SKIP | XML::LibXML::InputCallback::
0 | 0 | 0 | 0s | 0s | _callback_close | XML::LibXML::InputCallback::
0 | 0 | 0 | 0s | 0s | _callback_match | XML::LibXML::InputCallback::
0 | 0 | 0 | 0s | 0s | _callback_open | XML::LibXML::InputCallback::
0 | 0 | 0 | 0s | 0s | _callback_read | XML::LibXML::InputCallback::
0 | 0 | 0 | 0s | 0s | register_callbacks | XML::LibXML::InputCallback::
0 | 0 | 0 | 0s | 0s | unregister_callbacks | XML::LibXML::InputCallback::
0 | 0 | 0 | 0s | 0s | CLONE_SKIP | XML::LibXML::NamedNodeMap::
0 | 0 | 0 | 0s | 0s | getNamedItem | XML::LibXML::NamedNodeMap::
0 | 0 | 0 | 0s | 0s | getNamedItemNS | XML::LibXML::NamedNodeMap::
0 | 0 | 0 | 0s | 0s | item | XML::LibXML::NamedNodeMap::
0 | 0 | 0 | 0s | 0s | length | XML::LibXML::NamedNodeMap::
0 | 0 | 0 | 0s | 0s | new | XML::LibXML::NamedNodeMap::
0 | 0 | 0 | 0s | 0s | nodes | XML::LibXML::NamedNodeMap::
0 | 0 | 0 | 0s | 0s | removeNamedItem | XML::LibXML::NamedNodeMap::
0 | 0 | 0 | 0s | 0s | removeNamedItemNS | XML::LibXML::NamedNodeMap::
0 | 0 | 0 | 0s | 0s | setNamedItem | XML::LibXML::NamedNodeMap::
0 | 0 | 0 | 0s | 0s | setNamedItemNS | XML::LibXML::NamedNodeMap::
0 | 0 | 0 | 0s | 0s | CLONE_SKIP | XML::LibXML::Namespace::
0 | 0 | 0 | 0s | 0s | getName | XML::LibXML::Namespace::
0 | 0 | 0 | 0s | 0s | getNamespaceURI | XML::LibXML::Namespace::
0 | 0 | 0 | 0s | 0s | getNamespaces | XML::LibXML::Namespace::
0 | 0 | 0 | 0s | 0s | getPrefix | XML::LibXML::Namespace::
0 | 0 | 0 | 0s | 0s | isEqualNode | XML::LibXML::Namespace::
0 | 0 | 0 | 0s | 0s | isSameNode | XML::LibXML::Namespace::
0 | 0 | 0 | 0s | 0s | name | XML::LibXML::Namespace::
0 | 0 | 0 | 0s | 0s | nodeName | XML::LibXML::Namespace::
0 | 0 | 0 | 0s | 0s | prefix | XML::LibXML::Namespace::
0 | 0 | 0 | 0s | 0s | CLONE_SKIP | XML::LibXML::Node::
0 | 0 | 0 | 0s | 0s | attributes | XML::LibXML::Node::
0 | 0 | 0 | 0s | 0s | childNodes | XML::LibXML::Node::
0 | 0 | 0 | 0s | 0s | exists | XML::LibXML::Node::
0 | 0 | 0 | 0s | 0s | find | XML::LibXML::Node::
0 | 0 | 0 | 0s | 0s | findbool | XML::LibXML::Node::
0 | 0 | 0 | 0s | 0s | findnodes | XML::LibXML::Node::
0 | 0 | 0 | 0s | 0s | findvalue | XML::LibXML::Node::
0 | 0 | 0 | 0s | 0s | getChildNodes | XML::LibXML::Node::
0 | 0 | 0 | 0s | 0s | isSupported | XML::LibXML::Node::
0 | 0 | 0 | 0s | 0s | nonBlankChildNodes | XML::LibXML::Node::
0 | 0 | 0 | 0s | 0s | setOwnerDocument | XML::LibXML::Node::
0 | 0 | 0 | 0s | 0s | toStringC14N | XML::LibXML::Node::
0 | 0 | 0 | 0s | 0s | toStringEC14N | XML::LibXML::Node::
0 | 0 | 0 | 0s | 0s | setData | XML::LibXML::PI::
0 | 0 | 0 | 0s | 0s | CLONE_SKIP | XML::LibXML::Pattern::
0 | 0 | 0 | 0s | 0s | new | XML::LibXML::Pattern::
0 | 0 | 0 | 0s | 0s | CLONE_SKIP | XML::LibXML::RegExp::
0 | 0 | 0 | 0s | 0s | new | XML::LibXML::RegExp::
0 | 0 | 0 | 0s | 0s | CLONE_SKIP | XML::LibXML::RelaxNG::
0 | 0 | 0 | 0s | 0s | new | XML::LibXML::RelaxNG::
0 | 0 | 0 | 0s | 0s | CLONE_SKIP | XML::LibXML::Schema::
0 | 0 | 0 | 0s | 0s | new | XML::LibXML::Schema::
0 | 0 | 0 | 0s | 0s | attributes | XML::LibXML::Text::
0 | 0 | 0 | 0s | 0s | deleteDataString | XML::LibXML::Text::
0 | 0 | 0 | 0s | 0s | replaceDataRegEx | XML::LibXML::Text::
0 | 0 | 0 | 0s | 0s | replaceDataString | XML::LibXML::Text::
0 | 0 | 0 | 0s | 0s | VERSION | XML::LibXML::
0 | 0 | 0 | 0s | 0s | CLONE_SKIP | XML::LibXML::XPathExpression::
0 | 0 | 0 | 0s | 0s | CLONE_SKIP | XML::LibXML::_SAXParser::
0 | 0 | 0 | 0s | 0s | error | XML::LibXML::_SAXParser::
0 | 0 | 0 | 0s | 0s | fatal_error | XML::LibXML::_SAXParser::
0 | 0 | 0 | 0s | 0s | warning | XML::LibXML::_SAXParser::
0 | 0 | 0 | 0s | 0s | __parser_option | XML::LibXML::
0 | 0 | 0 | 0s | 0s | __proxy_registry | XML::LibXML::
0 | 0 | 0 | 0s | 0s | __read | XML::LibXML::
0 | 0 | 0 | 0s | 0s | __write | XML::LibXML::
0 | 0 | 0 | 0s | 0s | _auto_expand | XML::LibXML::
0 | 0 | 0 | 0s | 0s | _clone | XML::LibXML::
0 | 0 | 0 | 0s | 0s | _html_options | XML::LibXML::
0 | 0 | 0 | 0s | 0s | _parser_options | XML::LibXML::
0 | 0 | 0 | 0s | 0s | base_uri | XML::LibXML::
0 | 0 | 0 | 0s | 0s | callbacks | XML::LibXML::
0 | 0 | 0 | 0s | 0s | clean_namespaces | XML::LibXML::
0 | 0 | 0 | 0s | 0s | complete_attributes | XML::LibXML::
0 | 0 | 0 | 0s | 0s | createDocument | XML::LibXML::
0 | 0 | 0 | 0s | 0s | expand_entities | XML::LibXML::
0 | 0 | 0 | 0s | 0s | expand_xinclude | XML::LibXML::
0 | 0 | 0 | 0s | 0s | externalEntityLoader | XML::LibXML::
0 | 0 | 0 | 0s | 0s | finish_push | XML::LibXML::
0 | 0 | 0 | 0s | 0s | gdome_dom | XML::LibXML::
0 | 0 | 0 | 0s | 0s | get_option | XML::LibXML::
0 | 0 | 0 | 0s | 0s | init_push | XML::LibXML::
0 | 0 | 0 | 0s | 0s | input_callbacks | XML::LibXML::
0 | 0 | 0 | 0s | 0s | keep_blanks | XML::LibXML::
0 | 0 | 0 | 0s | 0s | line_numbers | XML::LibXML::
0 | 0 | 0 | 0s | 0s | load_ext_dtd | XML::LibXML::
0 | 0 | 0 | 0s | 0s | load_html | XML::LibXML::
0 | 0 | 0 | 0s | 0s | load_xml | XML::LibXML::
0 | 0 | 0 | 0s | 0s | no_network | XML::LibXML::
0 | 0 | 0 | 0s | 0s | option_exists | XML::LibXML::
0 | 0 | 0 | 0s | 0s | parse_balanced_chunk | XML::LibXML::
0 | 0 | 0 | 0s | 0s | parse_chunk | XML::LibXML::
0 | 0 | 0 | 0s | 0s | parse_fh | XML::LibXML::
0 | 0 | 0 | 0s | 0s | parse_file | XML::LibXML::
0 | 0 | 0 | 0s | 0s | parse_html_fh | XML::LibXML::
0 | 0 | 0 | 0s | 0s | parse_html_file | XML::LibXML::
0 | 0 | 0 | 0s | 0s | parse_html_string | XML::LibXML::
0 | 0 | 0 | 0s | 0s | parse_xml_chunk | XML::LibXML::
0 | 0 | 0 | 0s | 0s | pedantic_parser | XML::LibXML::
0 | 0 | 0 | 0s | 0s | processXIncludes | XML::LibXML::
0 | 0 | 0 | 0s | 0s | process_xincludes | XML::LibXML::
0 | 0 | 0 | 0s | 0s | push | XML::LibXML::
0 | 0 | 0 | 0s | 0s | recover | XML::LibXML::
0 | 0 | 0 | 0s | 0s | recover_silently | XML::LibXML::
0 | 0 | 0 | 0s | 0s | set_option | XML::LibXML::
0 | 0 | 0 | 0s | 0s | set_options | XML::LibXML::
0 | 0 | 0 | 0s | 0s | threads_shared_enabled | XML::LibXML::
0 | 0 | 0 | 0s | 0s | validation | XML::LibXML::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | # $Id$ | ||||
2 | # | ||||
3 | # | ||||
4 | # This is free software, you may use it and distribute it under the same terms as | ||||
5 | # Perl itself. | ||||
6 | # | ||||
7 | # Copyright 2001-2003 AxKit.com Ltd., 2002-2006 Christian Glahn, 2006-2009 Petr Pajas | ||||
8 | # | ||||
9 | # | ||||
10 | |||||
11 | package XML::LibXML; | ||||
12 | |||||
13 | 2 | 215µs | 2 | 274µs | # spent 176µs (78+98) within XML::LibXML::BEGIN@13 which was called:
# once (78µs+98µs) by XML::LibXML::SAX::BEGIN@17 at line 13 # spent 176µs making 1 call to XML::LibXML::BEGIN@13
# spent 98µs making 1 call to strict::import |
14 | 1 | 40µs | 1 | 1.22ms | # spent 1.28ms (54µs+1.22) within XML::LibXML::BEGIN@14 which was called:
# once (54µs+1.22ms) by XML::LibXML::SAX::BEGIN@17 at line 18 # spent 1.22ms making 1 call to vars::import |
15 | $skipDTD $skipXMLDeclaration $setTagCompression | ||||
16 | $MatchCB $ReadCB $OpenCB $CloseCB %PARSER_FLAGS | ||||
17 | $XML_LIBXML_PARSE_DEFAULTS | ||||
18 | 1 | 138µs | 1 | 1.28ms | ); # spent 1.28ms making 1 call to XML::LibXML::BEGIN@14 |
19 | 2 | 172µs | 2 | 542µs | # spent 299µs (56+243) within XML::LibXML::BEGIN@19 which was called:
# once (56µs+243µs) by XML::LibXML::SAX::BEGIN@17 at line 19 # spent 299µs making 1 call to XML::LibXML::BEGIN@19
# spent 243µs making 1 call to Exporter::import |
20 | |||||
21 | 2 | 163µs | 2 | 495µs | # spent 272µs (50+222) within XML::LibXML::BEGIN@21 which was called:
# once (50µs+222µs) by XML::LibXML::SAX::BEGIN@17 at line 21 # spent 272µs making 1 call to XML::LibXML::BEGIN@21
# spent 222µs making 1 call to constant::import |
22 | 2 | 153µs | 2 | 464µs | # spent 258µs (51+206) within XML::LibXML::BEGIN@22 which was called:
# once (51µs+206µs) by XML::LibXML::SAX::BEGIN@17 at line 22 # spent 258µs making 1 call to XML::LibXML::BEGIN@22
# spent 206µs making 1 call to constant::import |
23 | |||||
24 | 2 | 663µs | 1 | 76.1ms | # spent 76.1ms (12.0+64.1) within XML::LibXML::BEGIN@24 which was called:
# once (12.0ms+64.1ms) by XML::LibXML::SAX::BEGIN@17 at line 24 # spent 76.1ms making 1 call to XML::LibXML::BEGIN@24 |
25 | 2 | 704µs | 1 | 15.8ms | # spent 15.8ms (4.29+11.5) within XML::LibXML::BEGIN@25 which was called:
# once (4.29ms+11.5ms) by XML::LibXML::SAX::BEGIN@17 at line 25 # spent 15.8ms making 1 call to XML::LibXML::BEGIN@25 |
26 | 2 | 714µs | 1 | 5.69ms | # spent 5.69ms (4.59+1.09) within XML::LibXML::BEGIN@26 which was called:
# once (4.59ms+1.09ms) by XML::LibXML::SAX::BEGIN@17 at line 26 # spent 5.69ms making 1 call to XML::LibXML::BEGIN@26 |
27 | 2 | 356µs | 2 | 289µs | # spent 176µs (64+113) within XML::LibXML::BEGIN@27 which was called:
# once (64µs+113µs) by XML::LibXML::SAX::BEGIN@17 at line 27 # spent 176µs making 1 call to XML::LibXML::BEGIN@27
# spent 113µs making 1 call to Exporter::import |
28 | |||||
29 | # spent 27.3ms (316µs+26.9) within XML::LibXML::BEGIN@29 which was called:
# once (316µs+26.9ms) by XML::LibXML::SAX::BEGIN@17 at line 154 | ||||
30 | 1 | 4µs | $VERSION = "1.90"; # VERSION TEMPLATE: DO NOT CHANGE | ||
31 | 1 | 1µs | $ABI_VERSION = 2; | ||
32 | 1 | 3µs | require Exporter; | ||
33 | 1 | 2µs | require DynaLoader; | ||
34 | 1 | 55µs | @ISA = qw(DynaLoader Exporter); | ||
35 | |||||
36 | 2 | 1.65ms | 2 | 829µs | # spent 442µs (54+388) within XML::LibXML::BEGIN@36 which was called:
# once (54µs+388µs) by XML::LibXML::SAX::BEGIN@17 at line 36 # spent 442µs making 1 call to XML::LibXML::BEGIN@36
# spent 388µs making 1 call to vars::import |
37 | |||||
38 | sub VERSION { | ||||
39 | my $class = shift; | ||||
40 | my ($caller) = caller; | ||||
41 | my $req_abi = $ABI_VERSION; | ||||
42 | if (UNIVERSAL::can($caller,'REQUIRE_XML_LIBXML_ABI_VERSION')) { | ||||
43 | $req_abi = $caller->REQUIRE_XML_LIBXML_ABI_VERSION(); | ||||
44 | } elsif ($caller eq 'XML::LibXSLT') { | ||||
45 | # XML::LibXSLT without REQUIRE_XML_LIBXML_ABI_VERSION is an old and incompatible version | ||||
46 | $req_abi = 1; | ||||
47 | } | ||||
48 | unless ($req_abi == $ABI_VERSION) { | ||||
49 | my $ver = @_ ? ' '.$_[0] : ''; | ||||
50 | die ("This version of $caller requires XML::LibXML$ver (ABI $req_abi), which is incompatible with currently installed XML::LibXML $VERSION (ABI $ABI_VERSION). Please upgrade $caller, XML::LibXML, or both!"); | ||||
51 | } | ||||
52 | return $class->UNIVERSAL::VERSION(@_) | ||||
53 | } | ||||
54 | |||||
55 | #-------------------------------------------------------------------------# | ||||
56 | # export information # | ||||
57 | #-------------------------------------------------------------------------# | ||||
58 | 1 | 65µs | %EXPORT_TAGS = ( | ||
59 | all => [qw( | ||||
60 | XML_ELEMENT_NODE | ||||
61 | XML_ATTRIBUTE_NODE | ||||
62 | XML_TEXT_NODE | ||||
63 | XML_CDATA_SECTION_NODE | ||||
64 | XML_ENTITY_REF_NODE | ||||
65 | XML_ENTITY_NODE | ||||
66 | XML_PI_NODE | ||||
67 | XML_COMMENT_NODE | ||||
68 | XML_DOCUMENT_NODE | ||||
69 | XML_DOCUMENT_TYPE_NODE | ||||
70 | XML_DOCUMENT_FRAG_NODE | ||||
71 | XML_NOTATION_NODE | ||||
72 | XML_HTML_DOCUMENT_NODE | ||||
73 | XML_DTD_NODE | ||||
74 | XML_ELEMENT_DECL | ||||
75 | XML_ATTRIBUTE_DECL | ||||
76 | XML_ENTITY_DECL | ||||
77 | XML_NAMESPACE_DECL | ||||
78 | XML_XINCLUDE_END | ||||
79 | XML_XINCLUDE_START | ||||
80 | encodeToUTF8 | ||||
81 | decodeFromUTF8 | ||||
82 | XML_XMLNS_NS | ||||
83 | XML_XML_NS | ||||
84 | )], | ||||
85 | libxml => [qw( | ||||
86 | XML_ELEMENT_NODE | ||||
87 | XML_ATTRIBUTE_NODE | ||||
88 | XML_TEXT_NODE | ||||
89 | XML_CDATA_SECTION_NODE | ||||
90 | XML_ENTITY_REF_NODE | ||||
91 | XML_ENTITY_NODE | ||||
92 | XML_PI_NODE | ||||
93 | XML_COMMENT_NODE | ||||
94 | XML_DOCUMENT_NODE | ||||
95 | XML_DOCUMENT_TYPE_NODE | ||||
96 | XML_DOCUMENT_FRAG_NODE | ||||
97 | XML_NOTATION_NODE | ||||
98 | XML_HTML_DOCUMENT_NODE | ||||
99 | XML_DTD_NODE | ||||
100 | XML_ELEMENT_DECL | ||||
101 | XML_ATTRIBUTE_DECL | ||||
102 | XML_ENTITY_DECL | ||||
103 | XML_NAMESPACE_DECL | ||||
104 | XML_XINCLUDE_END | ||||
105 | XML_XINCLUDE_START | ||||
106 | )], | ||||
107 | encoding => [qw( | ||||
108 | encodeToUTF8 | ||||
109 | decodeFromUTF8 | ||||
110 | )], | ||||
111 | ns => [qw( | ||||
112 | XML_XMLNS_NS | ||||
113 | XML_XML_NS | ||||
114 | )], | ||||
115 | ); | ||||
116 | |||||
117 | @EXPORT_OK = ( | ||||
118 | 1 | 21µs | @{$EXPORT_TAGS{all}}, | ||
119 | ); | ||||
120 | |||||
121 | @EXPORT = ( | ||||
122 | 1 | 18µs | @{$EXPORT_TAGS{all}}, | ||
123 | ); | ||||
124 | |||||
125 | #-------------------------------------------------------------------------# | ||||
126 | # initialization of the global variables # | ||||
127 | #-------------------------------------------------------------------------# | ||||
128 | 1 | 1µs | $skipDTD = 0; | ||
129 | 1 | 800ns | $skipXMLDeclaration = 0; | ||
130 | 1 | 600ns | $setTagCompression = 0; | ||
131 | |||||
132 | 1 | 1µs | $MatchCB = undef; | ||
133 | 1 | 900ns | $ReadCB = undef; | ||
134 | 1 | 500ns | $OpenCB = undef; | ||
135 | 1 | 600ns | $CloseCB = undef; | ||
136 | |||||
137 | # if ($threads::threads) { | ||||
138 | # our $__THREADS_TID = 0; | ||||
139 | # eval q{ | ||||
140 | # use threads::shared; | ||||
141 | # our $__PROXY_NODE_REGISTRY_MUTEX :shared = 0; | ||||
142 | # }; | ||||
143 | # die $@ if $@; | ||||
144 | # } | ||||
145 | #-------------------------------------------------------------------------# | ||||
146 | # bootstrapping # | ||||
147 | #-------------------------------------------------------------------------# | ||||
148 | 1 | 47µs | 1 | 26.9ms | bootstrap XML::LibXML $VERSION; # spent 26.9ms making 1 call to DynaLoader::bootstrap |
149 | 1 | 46µs | undef &AUTOLOAD; | ||
150 | |||||
151 | 1 | 9µs | *encodeToUTF8 = \&XML::LibXML::Common::encodeToUTF8; | ||
152 | 1 | 23µs | *decodeFromUTF8 = \&XML::LibXML::Common::decodeFromUTF8; | ||
153 | |||||
154 | 1 | 174µs | 1 | 27.3ms | } # BEGIN # spent 27.3ms making 1 call to XML::LibXML::BEGIN@29 |
155 | |||||
156 | |||||
157 | #-------------------------------------------------------------------------# | ||||
158 | # libxml2 node names (see also XML::LibXML::Common # | ||||
159 | #-------------------------------------------------------------------------# | ||||
160 | 2 | 200µs | 2 | 537µs | # spent 299µs (61+238) within XML::LibXML::BEGIN@160 which was called:
# once (61µs+238µs) by XML::LibXML::SAX::BEGIN@17 at line 160 # spent 299µs making 1 call to XML::LibXML::BEGIN@160
# spent 238µs making 1 call to constant::import |
161 | 2 | 156µs | 2 | 413µs | # spent 231µs (49+182) within XML::LibXML::BEGIN@161 which was called:
# once (49µs+182µs) by XML::LibXML::SAX::BEGIN@17 at line 161 # spent 231µs making 1 call to XML::LibXML::BEGIN@161
# spent 182µs making 1 call to constant::import |
162 | 2 | 149µs | 2 | 380µs | # spent 213µs (46+167) within XML::LibXML::BEGIN@162 which was called:
# once (46µs+167µs) by XML::LibXML::SAX::BEGIN@17 at line 162 # spent 213µs making 1 call to XML::LibXML::BEGIN@162
# spent 167µs making 1 call to constant::import |
163 | 2 | 150µs | 2 | 373µs | # spent 210µs (48+163) within XML::LibXML::BEGIN@163 which was called:
# once (48µs+163µs) by XML::LibXML::SAX::BEGIN@17 at line 163 # spent 210µs making 1 call to XML::LibXML::BEGIN@163
# spent 163µs making 1 call to constant::import |
164 | 2 | 157µs | 2 | 459µs | # spent 253µs (47+206) within XML::LibXML::BEGIN@164 which was called:
# once (47µs+206µs) by XML::LibXML::SAX::BEGIN@17 at line 164 # spent 253µs making 1 call to XML::LibXML::BEGIN@164
# spent 206µs making 1 call to constant::import |
165 | 2 | 172µs | 2 | 392µs | # spent 219µs (46+173) within XML::LibXML::BEGIN@165 which was called:
# once (46µs+173µs) by XML::LibXML::SAX::BEGIN@17 at line 165 # spent 219µs making 1 call to XML::LibXML::BEGIN@165
# spent 173µs making 1 call to constant::import |
166 | 2 | 149µs | 2 | 394µs | # spent 226µs (57+169) within XML::LibXML::BEGIN@166 which was called:
# once (57µs+169µs) by XML::LibXML::SAX::BEGIN@17 at line 166 # spent 226µs making 1 call to XML::LibXML::BEGIN@166
# spent 169µs making 1 call to constant::import |
167 | 2 | 145µs | 2 | 375µs | # spent 210µs (45+165) within XML::LibXML::BEGIN@167 which was called:
# once (45µs+165µs) by XML::LibXML::SAX::BEGIN@17 at line 167 # spent 210µs making 1 call to XML::LibXML::BEGIN@167
# spent 165µs making 1 call to constant::import |
168 | 2 | 144µs | 2 | 368µs | # spent 207µs (46+161) within XML::LibXML::BEGIN@168 which was called:
# once (46µs+161µs) by XML::LibXML::SAX::BEGIN@17 at line 168 # spent 207µs making 1 call to XML::LibXML::BEGIN@168
# spent 161µs making 1 call to constant::import |
169 | 2 | 146µs | 2 | 368µs | # spent 207µs (46+161) within XML::LibXML::BEGIN@169 which was called:
# once (46µs+161µs) by XML::LibXML::SAX::BEGIN@17 at line 169 # spent 207µs making 1 call to XML::LibXML::BEGIN@169
# spent 161µs making 1 call to constant::import |
170 | 2 | 150µs | 2 | 368µs | # spent 207µs (46+161) within XML::LibXML::BEGIN@170 which was called:
# once (46µs+161µs) by XML::LibXML::SAX::BEGIN@17 at line 170 # spent 207µs making 1 call to XML::LibXML::BEGIN@170
# spent 161µs making 1 call to constant::import |
171 | 2 | 166µs | 2 | 367µs | # spent 207µs (47+160) within XML::LibXML::BEGIN@171 which was called:
# once (47µs+160µs) by XML::LibXML::SAX::BEGIN@17 at line 171 # spent 207µs making 1 call to XML::LibXML::BEGIN@171
# spent 160µs making 1 call to constant::import |
172 | 2 | 151µs | 2 | 420µs | # spent 233µs (47+186) within XML::LibXML::BEGIN@172 which was called:
# once (47µs+186µs) by XML::LibXML::SAX::BEGIN@17 at line 172 # spent 233µs making 1 call to XML::LibXML::BEGIN@172
# spent 186µs making 1 call to constant::import |
173 | 2 | 168µs | 2 | 378µs | # spent 211µs (45+166) within XML::LibXML::BEGIN@173 which was called:
# once (45µs+166µs) by XML::LibXML::SAX::BEGIN@17 at line 173 # spent 211µs making 1 call to XML::LibXML::BEGIN@173
# spent 166µs making 1 call to constant::import |
174 | 2 | 148µs | 2 | 378µs | # spent 211µs (45+166) within XML::LibXML::BEGIN@174 which was called:
# once (45µs+166µs) by XML::LibXML::SAX::BEGIN@17 at line 174 # spent 211µs making 1 call to XML::LibXML::BEGIN@174
# spent 166µs making 1 call to constant::import |
175 | 2 | 157µs | 2 | 447µs | # spent 247µs (48+200) within XML::LibXML::BEGIN@175 which was called:
# once (48µs+200µs) by XML::LibXML::SAX::BEGIN@17 at line 175 # spent 247µs making 1 call to XML::LibXML::BEGIN@175
# spent 200µs making 1 call to constant::import |
176 | 2 | 167µs | 2 | 391µs | # spent 219µs (47+172) within XML::LibXML::BEGIN@176 which was called:
# once (47µs+172µs) by XML::LibXML::SAX::BEGIN@17 at line 176 # spent 219µs making 1 call to XML::LibXML::BEGIN@176
# spent 172µs making 1 call to constant::import |
177 | 2 | 153µs | 2 | 384µs | # spent 217µs (49+168) within XML::LibXML::BEGIN@177 which was called:
# once (49µs+168µs) by XML::LibXML::SAX::BEGIN@17 at line 177 # spent 217µs making 1 call to XML::LibXML::BEGIN@177
# spent 168µs making 1 call to constant::import |
178 | 2 | 172µs | 2 | 376µs | # spent 211µs (47+164) within XML::LibXML::BEGIN@178 which was called:
# once (47µs+164µs) by XML::LibXML::SAX::BEGIN@17 at line 178 # spent 211µs making 1 call to XML::LibXML::BEGIN@178
# spent 164µs making 1 call to constant::import |
179 | 2 | 1.77ms | 2 | 390µs | # spent 219µs (47+172) within XML::LibXML::BEGIN@179 which was called:
# once (47µs+172µs) by XML::LibXML::SAX::BEGIN@17 at line 179 # spent 219µs making 1 call to XML::LibXML::BEGIN@179
# spent 172µs making 1 call to constant::import |
180 | |||||
181 | |||||
182 | # spent 4.87ms (330µs+4.54) within XML::LibXML::import which was called 3 times, avg 1.62ms/call:
# once (180µs+2.15ms) by XML::LibXML::Element::BEGIN@1487 at line 1487
# once (88µs+1.28ms) by XML::LibXML::NamedNodeMap::BEGIN@1830 at line 1830
# once (62µs+1.11ms) by XML::LibXML::SAX::BEGIN@17 at line 17 of XML/LibXML/SAX.pm | ||||
183 | 3 | 12µs | my $package=shift; | ||
184 | 3 | 115µs | 3 | 7µs | if (grep /^:threads_shared$/, @_) { # spent 7µs making 3 calls to XML::LibXML::CORE:match, avg 2µs/call |
185 | require threads; | ||||
186 | if (!defined($__threads_shared)) { | ||||
187 | if (INIT_THREAD_SUPPORT()) { | ||||
188 | eval q{ | ||||
189 | use threads::shared; | ||||
190 | share($__PROXY_NODE_REGISTRY_MUTEX); | ||||
191 | }; | ||||
192 | if ($@) { # something went wrong | ||||
193 | DISABLE_THREAD_SUPPORT(); # leave the library in a usable state | ||||
194 | die $@; # and die | ||||
195 | } | ||||
196 | $__PROXY_NODE_REGISTRY = XML::LibXML::HashTable->new(); | ||||
197 | $__threads_shared=1; | ||||
198 | } else { | ||||
199 | croak("XML::LibXML or Perl compiled without ithread support!"); | ||||
200 | } | ||||
201 | } elsif (!$__threads_shared) { | ||||
202 | croak("XML::LibXML already loaded without thread support. Too late to enable thread support!"); | ||||
203 | } | ||||
204 | } elsif (defined $XML::LibXML::__loaded) { | ||||
205 | 1 | 3µs | $__threads_shared=0 if not defined $__threads_shared; | ||
206 | } | ||||
207 | 3 | 177µs | 6 | 347µs | __PACKAGE__->export_to_level(1,$package,grep !/^:threads(_shared)?$/,@_); # spent 344µs making 3 calls to Exporter::export_to_level, avg 115µs/call
# spent 4µs making 3 calls to XML::LibXML::CORE:match, avg 1µs/call |
208 | } | ||||
209 | |||||
210 | sub threads_shared_enabled { | ||||
211 | return $__threads_shared ? 1 : 0; | ||||
212 | } | ||||
213 | |||||
214 | # if ($threads::threads) { | ||||
215 | # our $__PROXY_NODE_REGISTRY = XML::LibXML::HashTable->new(); | ||||
216 | # } | ||||
217 | |||||
218 | #-------------------------------------------------------------------------# | ||||
219 | # test exact version (up to patch-level) # | ||||
220 | #-------------------------------------------------------------------------# | ||||
221 | { | ||||
222 | 2 | 124µs | 2 | 50µs | my ($runtime_version) = LIBXML_RUNTIME_VERSION() =~ /^(\d+)/; # spent 31µs making 1 call to XML::LibXML::LIBXML_RUNTIME_VERSION
# spent 19µs making 1 call to XML::LibXML::CORE:match |
223 | 1 | 50µs | 1 | 15µs | if ( $runtime_version < LIBXML_VERSION ) { # spent 15µs making 1 call to XML::LibXML::LIBXML_VERSION |
224 | warn "Warning: XML::LibXML compiled against libxml2 ".LIBXML_VERSION. | ||||
225 | ", but runtime libxml2 is older $runtime_version\n"; | ||||
226 | } | ||||
227 | } | ||||
228 | |||||
229 | |||||
230 | #-------------------------------------------------------------------------# | ||||
231 | # parser flags # | ||||
232 | #-------------------------------------------------------------------------# | ||||
233 | |||||
234 | # Copied directly from http://xmlsoft.org/html/libxml-parser.html#xmlParserOption | ||||
235 | # spent 2.23ms (103µs+2.13) within XML::LibXML::BEGIN@235 which was called:
# once (103µs+2.13ms) by XML::LibXML::SAX::BEGIN@17 at line 258 | ||||
236 | 1 | 76µs | 1 | 2.13ms | XML_PARSE_RECOVER => 1, # recover on errors # spent 2.13ms making 1 call to constant::import |
237 | XML_PARSE_NOENT => 2, # substitute entities | ||||
238 | XML_PARSE_DTDLOAD => 4, # load the external subset | ||||
239 | XML_PARSE_DTDATTR => 8, # default DTD attributes | ||||
240 | XML_PARSE_DTDVALID => 16, # validate with the DTD | ||||
241 | XML_PARSE_NOERROR => 32, # suppress error reports | ||||
242 | XML_PARSE_NOWARNING => 64, # suppress warning reports | ||||
243 | XML_PARSE_PEDANTIC => 128, # pedantic error reporting | ||||
244 | XML_PARSE_NOBLANKS => 256, # remove blank nodes | ||||
245 | XML_PARSE_SAX1 => 512, # use the SAX1 interface internally | ||||
246 | XML_PARSE_XINCLUDE => 1024, # Implement XInclude substitition | ||||
247 | XML_PARSE_NONET => 2048, # Forbid network access | ||||
248 | XML_PARSE_NODICT => 4096, # Do not reuse the context dictionnary | ||||
249 | XML_PARSE_NSCLEAN => 8192, # remove redundant namespaces declarations | ||||
250 | XML_PARSE_NOCDATA => 16384, # merge CDATA as text nodes | ||||
251 | XML_PARSE_NOXINCNODE => 32768, # do not generate XINCLUDE START/END nodes | ||||
252 | XML_PARSE_COMPACT => 65536, # compact small text nodes; no modification of the tree allowed afterwards | ||||
253 | # (will possibly crash if you try to modify the tree) | ||||
254 | XML_PARSE_OLD10 => 131072, # parse using XML-1.0 before update 5 | ||||
255 | XML_PARSE_NOBASEFIX => 262144, # do not fixup XINCLUDE xml#base uris | ||||
256 | XML_PARSE_HUGE => 524288, # relax any hardcoded limit from the parser | ||||
257 | XML_PARSE_OLDSAX => 1048576, # parse using SAX2 interface from before 2.7.0 | ||||
258 | 1 | 28.7ms | 1 | 2.23ms | }; # spent 2.23ms making 1 call to XML::LibXML::BEGIN@235 |
259 | |||||
260 | 1 | 2µs | $XML_LIBXML_PARSE_DEFAULTS = ( XML_PARSE_NODICT | XML_PARSE_HUGE | XML_PARSE_DTDLOAD | XML_PARSE_NOENT ); | ||
261 | |||||
262 | # this hash is made global so that applications can add names for new | ||||
263 | # libxml2 parser flags as temporary workaround | ||||
264 | |||||
265 | 1 | 38µs | %PARSER_FLAGS = ( | ||
266 | recover => XML_PARSE_RECOVER, | ||||
267 | expand_entities => XML_PARSE_NOENT, | ||||
268 | load_ext_dtd => XML_PARSE_DTDLOAD, | ||||
269 | complete_attributes => XML_PARSE_DTDATTR, | ||||
270 | validation => XML_PARSE_DTDVALID, | ||||
271 | suppress_errors => XML_PARSE_NOERROR, | ||||
272 | suppress_warnings => XML_PARSE_NOWARNING, | ||||
273 | pedantic_parser => XML_PARSE_PEDANTIC, | ||||
274 | no_blanks => XML_PARSE_NOBLANKS, | ||||
275 | expand_xinclude => XML_PARSE_XINCLUDE, | ||||
276 | xinclude => XML_PARSE_XINCLUDE, | ||||
277 | no_network => XML_PARSE_NONET, | ||||
278 | clean_namespaces => XML_PARSE_NSCLEAN, | ||||
279 | no_cdata => XML_PARSE_NOCDATA, | ||||
280 | no_xinclude_nodes => XML_PARSE_NOXINCNODE, | ||||
281 | old10 => XML_PARSE_OLD10, | ||||
282 | no_base_fix => XML_PARSE_NOBASEFIX, | ||||
283 | huge => XML_PARSE_HUGE, | ||||
284 | oldsax => XML_PARSE_OLDSAX, | ||||
285 | ); | ||||
286 | |||||
287 | 1 | 16µs | my %OUR_FLAGS = ( | ||
288 | recover => 'XML_LIBXML_RECOVER', | ||||
289 | line_numbers => 'XML_LIBXML_LINENUMBERS', | ||||
290 | URI => 'XML_LIBXML_BASE_URI', | ||||
291 | base_uri => 'XML_LIBXML_BASE_URI', | ||||
292 | gdome => 'XML_LIBXML_GDOME', | ||||
293 | ext_ent_handler => 'ext_ent_handler', | ||||
294 | ); | ||||
295 | |||||
296 | sub _parser_options { | ||||
297 | my ($self, $opts) = @_; | ||||
298 | |||||
299 | # currently dictionaries break XML::LibXML memory management | ||||
300 | |||||
301 | my $flags; | ||||
302 | |||||
303 | if (ref($self)) { | ||||
304 | $flags = ($self->{XML_LIBXML_PARSER_OPTIONS}||0); | ||||
305 | } else { | ||||
306 | $flags = $XML_LIBXML_PARSE_DEFAULTS; # safety precaution | ||||
307 | } | ||||
308 | |||||
309 | my ($key, $value); | ||||
310 | while (($key,$value) = each %$opts) { | ||||
311 | my $f = $PARSER_FLAGS{ $key }; | ||||
312 | if (defined $f) { | ||||
313 | if ($value) { | ||||
314 | $flags |= $f | ||||
315 | } else { | ||||
316 | $flags &= ~$f; | ||||
317 | } | ||||
318 | } elsif ($key eq 'set_parser_flags') { # this can be used to pass flags XML::LibXML does not yet know about | ||||
319 | $flags |= $value; | ||||
320 | } elsif ($key eq 'unset_parser_flags') { | ||||
321 | $flags &= ~$value; | ||||
322 | } | ||||
323 | |||||
324 | } | ||||
325 | return $flags; | ||||
326 | } | ||||
327 | |||||
328 | 1 | 26µs | my %compatibility_flags = ( | ||
329 | XML_LIBXML_VALIDATION => 'validation', | ||||
330 | XML_LIBXML_EXPAND_ENTITIES => 'expand_entities', | ||||
331 | XML_LIBXML_PEDANTIC => 'pedantic_parser', | ||||
332 | XML_LIBXML_NONET => 'no_network', | ||||
333 | XML_LIBXML_EXT_DTD => 'load_ext_dtd', | ||||
334 | XML_LIBXML_COMPLETE_ATTR => 'complete_attributes', | ||||
335 | XML_LIBXML_EXPAND_XINCLUDE => 'expand_xinclude', | ||||
336 | XML_LIBXML_NSCLEAN => 'clean_namespaces', | ||||
337 | XML_LIBXML_KEEP_BLANKS => 'keep_blanks', | ||||
338 | XML_LIBXML_LINENUMBERS => 'line_numbers', | ||||
339 | ); | ||||
340 | |||||
341 | #-------------------------------------------------------------------------# | ||||
342 | # parser constructor # | ||||
343 | #-------------------------------------------------------------------------# | ||||
344 | |||||
345 | |||||
346 | # spent 95µs within XML::LibXML::new which was called 2 times, avg 48µs/call:
# 2 times (95µs+0s) by XML::LibXML::SAX::_parse_string at line 61 of XML/LibXML/SAX.pm, avg 48µs/call | ||||
347 | 2 | 6µs | my $class = shift; | ||
348 | 2 | 40µs | my $self = bless { | ||
349 | }, $class; | ||||
350 | 2 | 7µs | if (@_) { | ||
351 | my %opts = (); | ||||
352 | if (ref($_[0]) eq 'HASH') { | ||||
353 | %opts = %{$_[0]}; | ||||
354 | } else { | ||||
355 | # old interface | ||||
356 | my %args = @_; | ||||
357 | %opts=( | ||||
358 | map { | ||||
359 | (($compatibility_flags{ $_ }||$_) => $args{ $_ }) | ||||
360 | } keys %args | ||||
361 | ); | ||||
362 | } | ||||
363 | # parser flags | ||||
364 | $opts{no_blanks} = !$opts{keep_blanks} if exists($opts{keep_blanks}) and !exists($opts{no_blanks}); | ||||
365 | |||||
366 | for (keys %OUR_FLAGS) { | ||||
367 | $self->{$OUR_FLAGS{$_}} = delete $opts{$_}; | ||||
368 | } | ||||
369 | $class->load_catalog(delete($opts{catalog})) if $opts{catalog}; | ||||
370 | |||||
371 | $self->{XML_LIBXML_PARSER_OPTIONS} = XML::LibXML->_parser_options(\%opts); | ||||
372 | |||||
373 | # store remaining unknown options directly in $self | ||||
374 | for (keys %opts) { | ||||
375 | $self->{$_}=$opts{$_} unless exists $PARSER_FLAGS{$_}; | ||||
376 | } | ||||
377 | } else { | ||||
378 | 2 | 14µs | $self->{XML_LIBXML_PARSER_OPTIONS} = $XML_LIBXML_PARSE_DEFAULTS; | ||
379 | } | ||||
380 | 2 | 4µs | if ( defined $self->{Handler} ) { | ||
381 | $self->set_handler( $self->{Handler} ); | ||||
382 | } | ||||
383 | |||||
384 | 2 | 5µs | $self->{_State_} = 0; | ||
385 | 2 | 41µs | return $self; | ||
386 | } | ||||
387 | |||||
388 | sub _clone { | ||||
389 | my ($self)=@_; | ||||
390 | my $new = ref($self)->new({ | ||||
391 | recover => $self->{XML_LIBXML_RECOVER}, | ||||
392 | line_nubers => $self->{XML_LIBXML_LINENUMBERS}, | ||||
393 | base_uri => $self->{XML_LIBXML_BASE_URI}, | ||||
394 | gdome => $self->{XML_LIBXML_GDOME}, | ||||
395 | set_parser_flags => $self->{XML_LIBXML_PARSER_OPTIONS}, | ||||
396 | }); | ||||
397 | $new->input_callbacks($self->input_callbacks()); | ||||
398 | return $new; | ||||
399 | } | ||||
400 | |||||
401 | #-------------------------------------------------------------------------# | ||||
402 | # Threads support methods # | ||||
403 | #-------------------------------------------------------------------------# | ||||
404 | |||||
405 | # threads doc says CLONE's API may change in future, which would break | ||||
406 | # an XS method prototype | ||||
407 | sub CLONE { | ||||
408 | if ($XML::LibXML::__threads_shared) { | ||||
409 | XML::LibXML::_CLONE( $_[0] ); | ||||
410 | } | ||||
411 | } | ||||
412 | |||||
413 | sub CLONE_SKIP { | ||||
414 | return $XML::LibXML::__threads_shared ? 0 : 1; | ||||
415 | } | ||||
416 | |||||
417 | sub __proxy_registry { | ||||
418 | my ($class)=caller; | ||||
419 | die "This version of $class uses API of XML::LibXML 1.66 which is not compatible with XML::LibXML $VERSION. Please upgrade $class!\n"; | ||||
420 | } | ||||
421 | |||||
422 | #-------------------------------------------------------------------------# | ||||
423 | # DOM Level 2 document constructor # | ||||
424 | #-------------------------------------------------------------------------# | ||||
425 | |||||
426 | sub createDocument { | ||||
427 | my $self = shift; | ||||
428 | if (!@_ or $_[0] =~ m/^\d\.\d$/) { | ||||
429 | # for backward compatibility | ||||
430 | return XML::LibXML::Document->new(@_); | ||||
431 | } | ||||
432 | else { | ||||
433 | # DOM API: createDocument(namespaceURI, qualifiedName, doctype?) | ||||
434 | my $doc = XML::LibXML::Document-> new; | ||||
435 | my $el = $doc->createElementNS(shift, shift); | ||||
436 | $doc->setDocumentElement($el); | ||||
437 | $doc->setExternalSubset(shift) if @_; | ||||
438 | return $doc; | ||||
439 | } | ||||
440 | } | ||||
441 | |||||
442 | #-------------------------------------------------------------------------# | ||||
443 | # callback functions # | ||||
444 | #-------------------------------------------------------------------------# | ||||
445 | |||||
446 | sub externalEntityLoader(&) | ||||
447 | { | ||||
448 | return _externalEntityLoader($_[0]); | ||||
449 | } | ||||
450 | |||||
451 | sub input_callbacks { | ||||
452 | my $self = shift; | ||||
453 | my $icbclass = shift; | ||||
454 | |||||
455 | if ( defined $icbclass ) { | ||||
456 | $self->{XML_LIBXML_CALLBACK_STACK} = $icbclass; | ||||
457 | } | ||||
458 | return $self->{XML_LIBXML_CALLBACK_STACK}; | ||||
459 | } | ||||
460 | |||||
461 | # spent 38µs within XML::LibXML::match_callback which was called 2 times, avg 19µs/call:
# 2 times (38µs+0s) by XML::LibXML::InputCallback::init_callbacks at line 2225, avg 19µs/call | ||||
462 | 2 | 4µs | my $self = shift; | ||
463 | 2 | 6µs | if ( ref $self ) { | ||
464 | 2 | 3µs | if ( scalar @_ ) { | ||
465 | $self->{XML_LIBXML_MATCH_CB} = shift; | ||||
466 | $self->{XML_LIBXML_CALLBACK_STACK} = undef; | ||||
467 | } | ||||
468 | 2 | 42µs | return $self->{XML_LIBXML_MATCH_CB}; | ||
469 | } | ||||
470 | else { | ||||
471 | $MatchCB = shift if scalar @_; | ||||
472 | return $MatchCB; | ||||
473 | } | ||||
474 | } | ||||
475 | |||||
476 | # spent 35µs within XML::LibXML::read_callback which was called 2 times, avg 17µs/call:
# 2 times (35µs+0s) by XML::LibXML::InputCallback::init_callbacks at line 2227, avg 17µs/call | ||||
477 | 2 | 3µs | my $self = shift; | ||
478 | 2 | 5µs | if ( ref $self ) { | ||
479 | 2 | 4µs | if ( scalar @_ ) { | ||
480 | $self->{XML_LIBXML_READ_CB} = shift; | ||||
481 | $self->{XML_LIBXML_CALLBACK_STACK} = undef; | ||||
482 | } | ||||
483 | 2 | 61µs | return $self->{XML_LIBXML_READ_CB}; | ||
484 | } | ||||
485 | else { | ||||
486 | $ReadCB = shift if scalar @_; | ||||
487 | return $ReadCB; | ||||
488 | } | ||||
489 | } | ||||
490 | |||||
491 | # spent 33µs within XML::LibXML::close_callback which was called 2 times, avg 17µs/call:
# 2 times (33µs+0s) by XML::LibXML::InputCallback::init_callbacks at line 2228, avg 17µs/call | ||||
492 | 2 | 4µs | my $self = shift; | ||
493 | 2 | 6µs | if ( ref $self ) { | ||
494 | 2 | 3µs | if ( scalar @_ ) { | ||
495 | $self->{XML_LIBXML_CLOSE_CB} = shift; | ||||
496 | $self->{XML_LIBXML_CALLBACK_STACK} = undef; | ||||
497 | } | ||||
498 | 2 | 41µs | return $self->{XML_LIBXML_CLOSE_CB}; | ||
499 | } | ||||
500 | else { | ||||
501 | $CloseCB = shift if scalar @_; | ||||
502 | return $CloseCB; | ||||
503 | } | ||||
504 | } | ||||
505 | |||||
506 | # spent 34µs within XML::LibXML::open_callback which was called 2 times, avg 17µs/call:
# 2 times (34µs+0s) by XML::LibXML::InputCallback::init_callbacks at line 2226, avg 17µs/call | ||||
507 | 2 | 4µs | my $self = shift; | ||
508 | 2 | 6µs | if ( ref $self ) { | ||
509 | 2 | 3µs | if ( scalar @_ ) { | ||
510 | $self->{XML_LIBXML_OPEN_CB} = shift; | ||||
511 | $self->{XML_LIBXML_CALLBACK_STACK} = undef; | ||||
512 | } | ||||
513 | 2 | 41µs | return $self->{XML_LIBXML_OPEN_CB}; | ||
514 | } | ||||
515 | else { | ||||
516 | $OpenCB = shift if scalar @_; | ||||
517 | return $OpenCB; | ||||
518 | } | ||||
519 | } | ||||
520 | |||||
521 | sub callbacks { | ||||
522 | my $self = shift; | ||||
523 | if ( ref $self ) { | ||||
524 | if (@_) { | ||||
525 | my ($match, $open, $read, $close) = @_; | ||||
526 | @{$self}{qw(XML_LIBXML_MATCH_CB XML_LIBXML_OPEN_CB XML_LIBXML_READ_CB XML_LIBXML_CLOSE_CB)} = ($match, $open, $read, $close); | ||||
527 | $self->{XML_LIBXML_CALLBACK_STACK} = undef; | ||||
528 | } | ||||
529 | else { | ||||
530 | return @{$self}{qw(XML_LIBXML_MATCH_CB XML_LIBXML_OPEN_CB XML_LIBXML_READ_CB XML_LIBXML_CLOSE_CB)}; | ||||
531 | } | ||||
532 | } | ||||
533 | else { | ||||
534 | if (@_) { | ||||
535 | ( $MatchCB, $OpenCB, $ReadCB, $CloseCB ) = @_; | ||||
536 | } | ||||
537 | else { | ||||
538 | return ( $MatchCB, $OpenCB, $ReadCB, $CloseCB ); | ||||
539 | } | ||||
540 | } | ||||
541 | } | ||||
542 | |||||
543 | #-------------------------------------------------------------------------# | ||||
544 | # internal member variable manipulation # | ||||
545 | #-------------------------------------------------------------------------# | ||||
546 | sub __parser_option { | ||||
547 | my ($self, $opt) = @_; | ||||
548 | if (@_>2) { | ||||
549 | if ($_[2]) { | ||||
550 | $self->{XML_LIBXML_PARSER_OPTIONS} |= $opt; | ||||
551 | return 1; | ||||
552 | } else { | ||||
553 | $self->{XML_LIBXML_PARSER_OPTIONS} &= ~$opt; | ||||
554 | return 0; | ||||
555 | } | ||||
556 | } else { | ||||
557 | return ($self->{XML_LIBXML_PARSER_OPTIONS} & $opt) ? 1 : 0; | ||||
558 | } | ||||
559 | } | ||||
560 | |||||
561 | sub option_exists { | ||||
562 | my ($self,$name)=@_; | ||||
563 | return ($PARSER_FLAGS{$name} || $OUR_FLAGS{$name}) ? 1 : 0; | ||||
564 | } | ||||
565 | sub get_option { | ||||
566 | my ($self,$name)=@_; | ||||
567 | my $flag = $OUR_FLAGS{$name}; | ||||
568 | return $self->{$flag} if $flag; | ||||
569 | $flag = $PARSER_FLAGS{$name}; | ||||
570 | return $self->__parser_option($flag) if $flag; | ||||
571 | warn "XML::LibXML::get_option: unknown parser option $name\n"; | ||||
572 | return undef; | ||||
573 | } | ||||
574 | sub set_option { | ||||
575 | my ($self,$name,$value)=@_; | ||||
576 | my $flag = $OUR_FLAGS{$name}; | ||||
577 | return ($self->{$flag}=$value) if $flag; | ||||
578 | $flag = $PARSER_FLAGS{$name}; | ||||
579 | return $self->__parser_option($flag,$value) if $flag; | ||||
580 | warn "XML::LibXML::get_option: unknown parser option $name\n"; | ||||
581 | return undef; | ||||
582 | } | ||||
583 | sub set_options { | ||||
584 | my $self=shift; | ||||
585 | my $opts; | ||||
586 | if (@_==1 and ref($_[0]) eq 'HASH') { | ||||
587 | $opts = $_[0]; | ||||
588 | } elsif (@_ % 2 == 0) { | ||||
589 | $opts={@_}; | ||||
590 | } else { | ||||
591 | croak("Odd number of elements passed to set_options"); | ||||
592 | } | ||||
593 | $self->set_option($_=>$opts->{$_}) foreach keys %$opts; | ||||
594 | return; | ||||
595 | } | ||||
596 | |||||
597 | sub validation { | ||||
598 | my $self = shift; | ||||
599 | return $self->__parser_option(XML_PARSE_DTDVALID,@_); | ||||
600 | } | ||||
601 | |||||
602 | sub recover { | ||||
603 | my $self = shift; | ||||
604 | if (scalar @_) { | ||||
605 | $self->{XML_LIBXML_RECOVER} = $_[0]; | ||||
606 | $self->__parser_option(XML_PARSE_RECOVER,@_); | ||||
607 | } | ||||
608 | return $self->{XML_LIBXML_RECOVER}; | ||||
609 | } | ||||
610 | |||||
611 | sub recover_silently { | ||||
612 | my $self = shift; | ||||
613 | my $arg = shift; | ||||
614 | (($arg == 1) ? $self->recover(2) : $self->recover($arg)) if defined($arg); | ||||
615 | return (($self->recover()||0) == 2) ? 1 : 0; | ||||
616 | } | ||||
617 | |||||
618 | sub expand_entities { | ||||
619 | my $self = shift; | ||||
620 | if (scalar(@_) and $_[0]) { | ||||
621 | return $self->__parser_option(XML_PARSE_NOENT | XML_PARSE_DTDLOAD,1); | ||||
622 | } | ||||
623 | return $self->__parser_option(XML_PARSE_NOENT,@_); | ||||
624 | } | ||||
625 | |||||
626 | sub keep_blanks { | ||||
627 | my $self = shift; | ||||
628 | my @args; # we have to negate the argument and return negated value, since | ||||
629 | # the actual flag is no_blanks | ||||
630 | if (scalar @_) { | ||||
631 | @args=($_[0] ? 0 : 1); | ||||
632 | } | ||||
633 | return $self->__parser_option(XML_PARSE_NOBLANKS,@args) ? 0 : 1; | ||||
634 | } | ||||
635 | |||||
636 | sub pedantic_parser { | ||||
637 | my $self = shift; | ||||
638 | return $self->__parser_option(XML_PARSE_PEDANTIC,@_); | ||||
639 | } | ||||
640 | |||||
641 | sub line_numbers { | ||||
642 | my $self = shift; | ||||
643 | $self->{XML_LIBXML_LINENUMBERS} = shift if scalar @_; | ||||
644 | return $self->{XML_LIBXML_LINENUMBERS}; | ||||
645 | } | ||||
646 | |||||
647 | sub no_network { | ||||
648 | my $self = shift; | ||||
649 | return $self->__parser_option(XML_PARSE_NONET,@_); | ||||
650 | } | ||||
651 | |||||
652 | sub load_ext_dtd { | ||||
653 | my $self = shift; | ||||
654 | return $self->__parser_option(XML_PARSE_DTDLOAD,@_); | ||||
655 | } | ||||
656 | |||||
657 | sub complete_attributes { | ||||
658 | my $self = shift; | ||||
659 | return $self->__parser_option(XML_PARSE_DTDATTR,@_); | ||||
660 | } | ||||
661 | |||||
662 | sub expand_xinclude { | ||||
663 | my $self = shift; | ||||
664 | return $self->__parser_option(XML_PARSE_XINCLUDE,@_); | ||||
665 | } | ||||
666 | |||||
667 | sub base_uri { | ||||
668 | my $self = shift; | ||||
669 | $self->{XML_LIBXML_BASE_URI} = shift if scalar @_; | ||||
670 | return $self->{XML_LIBXML_BASE_URI}; | ||||
671 | } | ||||
672 | |||||
673 | sub gdome_dom { | ||||
674 | my $self = shift; | ||||
675 | $self->{XML_LIBXML_GDOME} = shift if scalar @_; | ||||
676 | return $self->{XML_LIBXML_GDOME}; | ||||
677 | } | ||||
678 | |||||
679 | sub clean_namespaces { | ||||
680 | my $self = shift; | ||||
681 | return $self->__parser_option(XML_PARSE_NSCLEAN,@_); | ||||
682 | } | ||||
683 | |||||
684 | #-------------------------------------------------------------------------# | ||||
685 | # set the optional SAX(2) handler # | ||||
686 | #-------------------------------------------------------------------------# | ||||
687 | # spent 128µs within XML::LibXML::set_handler which was called 4 times, avg 32µs/call:
# 2 times (65µs+0s) by XML::LibXML::SAX::_parse at line 107 of XML/LibXML/SAX.pm, avg 32µs/call
# 2 times (64µs+0s) by XML::LibXML::SAX::_parse at line 97 of XML/LibXML/SAX.pm, avg 32µs/call | ||||
688 | 4 | 12µs | my $self = shift; | ||
689 | 4 | 87µs | if ( defined $_[0] ) { | ||
690 | 2 | 9µs | $self->{HANDLER} = $_[0]; | ||
691 | |||||
692 | 2 | 9µs | $self->{SAX_ELSTACK} = []; | ||
693 | 2 | 14µs | $self->{SAX} = {State => 0}; | ||
694 | } | ||||
695 | else { | ||||
696 | # undef SAX handling | ||||
697 | 2 | 13µs | $self->{SAX_ELSTACK} = []; | ||
698 | 2 | 10µs | delete $self->{HANDLER}; | ||
699 | 2 | 11µs | delete $self->{SAX}; | ||
700 | } | ||||
701 | } | ||||
702 | |||||
703 | #-------------------------------------------------------------------------# | ||||
704 | # helper functions # | ||||
705 | #-------------------------------------------------------------------------# | ||||
706 | sub _auto_expand { | ||||
707 | my ( $self, $result, $uri ) = @_; | ||||
708 | |||||
709 | $result->setBaseURI( $uri ) if defined $uri; | ||||
710 | |||||
711 | if ( $self->expand_xinclude ) { | ||||
712 | $self->{_State_} = 1; | ||||
713 | eval { $self->processXIncludes($result); }; | ||||
714 | my $err = $@; | ||||
715 | $self->{_State_} = 0; | ||||
716 | if ($err) { | ||||
717 | $self->_cleanup_callbacks(); | ||||
718 | $result = undef; | ||||
719 | croak $err; | ||||
720 | } | ||||
721 | } | ||||
722 | return $result; | ||||
723 | } | ||||
724 | |||||
725 | # spent 729µs (157+572) within XML::LibXML::_init_callbacks which was called 2 times, avg 364µs/call:
# 2 times (157µs+572µs) by XML::LibXML::parse_string at line 828, avg 364µs/call | ||||
726 | 2 | 4µs | my $self = shift; | ||
727 | 2 | 5µs | my $icb = $self->{XML_LIBXML_CALLBACK_STACK}; | ||
728 | 2 | 4µs | unless ( defined $icb ) { | ||
729 | 2 | 53µs | 2 | 80µs | $self->{XML_LIBXML_CALLBACK_STACK} = XML::LibXML::InputCallback->new(); # spent 80µs making 2 calls to XML::LibXML::InputCallback::new, avg 40µs/call |
730 | 2 | 5µs | $icb = $self->{XML_LIBXML_CALLBACK_STACK}; | ||
731 | } | ||||
732 | |||||
733 | 2 | 55µs | 2 | 492µs | $icb->init_callbacks($self); # spent 492µs making 2 calls to XML::LibXML::InputCallback::init_callbacks, avg 246µs/call |
734 | } | ||||
735 | |||||
736 | # spent 194µs (63+132) within XML::LibXML::_cleanup_callbacks which was called 2 times, avg 97µs/call:
# 2 times (63µs+132µs) by XML::LibXML::parse_string at line 855, avg 97µs/call | ||||
737 | 2 | 5µs | my $self = shift; | ||
738 | 2 | 57µs | 2 | 132µs | $self->{XML_LIBXML_CALLBACK_STACK}->cleanup_callbacks(); # spent 132µs making 2 calls to XML::LibXML::InputCallback::cleanup_callbacks, avg 66µs/call |
739 | } | ||||
740 | |||||
741 | sub __read { | ||||
742 | read($_[0], $_[1], $_[2]); | ||||
743 | } | ||||
744 | |||||
745 | sub __write { | ||||
746 | if ( ref( $_[0] ) ) { | ||||
747 | $_[0]->write( $_[1], $_[2] ); | ||||
748 | } | ||||
749 | else { | ||||
750 | $_[0]->write( $_[1] ); | ||||
751 | } | ||||
752 | } | ||||
753 | |||||
754 | sub load_xml { | ||||
755 | my ($class_or_self) = shift; | ||||
756 | my %args = map { ref($_) eq 'HASH' ? (%$_) : $_ } @_; | ||||
757 | my $URI = delete($args{URI}); | ||||
758 | $URI = "$URI" if defined $URI; # stringify in case it is an URI object | ||||
759 | my $parser; | ||||
760 | if (ref($class_or_self)) { | ||||
761 | $parser = $class_or_self->_clone(); | ||||
762 | $parser->{XML_LIBXML_PARSER_OPTIONS} = $parser->_parser_options(\%args); | ||||
763 | } else { | ||||
764 | $parser = $class_or_self->new(\%args); | ||||
765 | } | ||||
766 | my $dom; | ||||
767 | if ( defined $args{location} ) { | ||||
768 | $dom = $parser->parse_file( "$args{location}" ); | ||||
769 | } | ||||
770 | elsif ( defined $args{string} ) { | ||||
771 | $dom = $parser->parse_string( $args{string}, $URI ); | ||||
772 | } | ||||
773 | elsif ( defined $args{IO} ) { | ||||
774 | $dom = $parser->parse_fh( $args{IO}, $URI ); | ||||
775 | } | ||||
776 | else { | ||||
777 | croak("XML::LibXML->load: specify location, string, or IO"); | ||||
778 | } | ||||
779 | return $dom; | ||||
780 | } | ||||
781 | |||||
782 | sub load_html { | ||||
783 | my ($class_or_self) = shift; | ||||
784 | my %args = map { ref($_) eq 'HASH' ? (%$_) : $_ } @_; | ||||
785 | my $URI = delete($args{URI}); | ||||
786 | $URI = "$URI" if defined $URI; # stringify in case it is an URI object | ||||
787 | my $parser; | ||||
788 | if (ref($class_or_self)) { | ||||
789 | $parser = $class_or_self->_clone(); | ||||
790 | } else { | ||||
791 | $parser = $class_or_self->new(); | ||||
792 | } | ||||
793 | my $dom; | ||||
794 | if ( defined $args{location} ) { | ||||
795 | $dom = $parser->parse_html_file( "$args{location}", \%args ); | ||||
796 | } | ||||
797 | elsif ( defined $args{string} ) { | ||||
798 | $dom = $parser->parse_html_string( $args{string}, \%args ); | ||||
799 | } | ||||
800 | elsif ( defined $args{IO} ) { | ||||
801 | $dom = $parser->parse_html_fh( $args{IO}, \%args ); | ||||
802 | } | ||||
803 | else { | ||||
804 | croak("XML::LibXML->load: specify location, string, or IO"); | ||||
805 | } | ||||
806 | return $dom; | ||||
807 | } | ||||
808 | |||||
809 | #-------------------------------------------------------------------------# | ||||
810 | # parsing functions # | ||||
811 | #-------------------------------------------------------------------------# | ||||
812 | # all parsing functions handle normal as SAX parsing at the same time. | ||||
813 | # note that SAX parsing is handled incomplete! use XML::LibXML::SAX for | ||||
814 | # complete parsing sequences | ||||
815 | #-------------------------------------------------------------------------# | ||||
816 | # spent 133ms (344µs+133) within XML::LibXML::parse_string which was called 2 times, avg 66.6ms/call:
# 2 times (344µs+133ms) by XML::LibXML::SAX::_parse at line 99 of XML/LibXML/SAX.pm, avg 66.6ms/call | ||||
817 | 2 | 6µs | my $self = shift; | ||
818 | 2 | 39µs | croak("parse_string is not a class method! Create a parser object with XML::LibXML->new first!") unless ref $self; | ||
819 | 2 | 6µs | croak("parse already in progress") if $self->{_State_}; | ||
820 | |||||
821 | 2 | 35µs | unless ( defined $_[0] and length $_[0] ) { | ||
822 | croak("Empty String"); | ||||
823 | } | ||||
824 | |||||
825 | 2 | 4µs | $self->{_State_} = 1; | ||
826 | 2 | 2µs | my $result; | ||
827 | |||||
828 | 2 | 27µs | 2 | 729µs | $self->_init_callbacks(); # spent 729µs making 2 calls to XML::LibXML::_init_callbacks, avg 364µs/call |
829 | |||||
830 | 2 | 9µs | if ( defined $self->{SAX} ) { | ||
831 | 2 | 41µs | my $string = shift; | ||
832 | 2 | 13µs | $self->{SAX_ELSTACK} = []; | ||
833 | 4 | 25.0ms | 621 | 207ms | eval { $result = $self->_parse_sax_string($string); }; # spent 132ms making 2 calls to XML::LibXML::_parse_sax_string, avg 65.9ms/call
# spent 51.2ms making 291 calls to XML::SAX::Base::characters, avg 176µs/call
# spent 13.2ms making 132 calls to XML::SAX::Base::start_element, avg 100µs/call
# spent 7.75ms making 132 calls to XML::SAX::Base::end_element, avg 59µs/call
# spent 2.18ms making 60 calls to XML::SAX::Base::comment, avg 36µs/call
# spent 316µs making 2 calls to XML::SAX::Base::start_document, avg 158µs/call
# spent 199µs making 2 calls to XML::SAX::Base::xml_decl, avg 99µs/call |
834 | 2 | 5µs | my $err = $@; | ||
835 | 2 | 9µs | $self->{_State_} = 0; | ||
836 | 2 | 4µs | if ($err) { | ||
837 | chomp $err unless ref $err; | ||||
838 | $self->_cleanup_callbacks(); | ||||
839 | croak $err; | ||||
840 | } | ||||
841 | } | ||||
842 | else { | ||||
843 | eval { $result = $self->_parse_string( @_ ); }; | ||||
844 | |||||
845 | my $err = $@; | ||||
846 | $self->{_State_} = 0; | ||||
847 | if ($err) { | ||||
848 | chomp $err unless ref $err; | ||||
849 | $self->_cleanup_callbacks(); | ||||
850 | croak $err; | ||||
851 | } | ||||
852 | |||||
853 | $result = $self->_auto_expand( $result, $self->{XML_LIBXML_BASE_URI} ); | ||||
854 | } | ||||
855 | 2 | 24µs | 2 | 194µs | $self->_cleanup_callbacks(); # spent 194µs making 2 calls to XML::LibXML::_cleanup_callbacks, avg 97µs/call |
856 | |||||
857 | 2 | 37µs | return $result; | ||
858 | } | ||||
859 | |||||
860 | sub parse_fh { | ||||
861 | my $self = shift; | ||||
862 | croak("parse_fh is not a class method! Create a parser object with XML::LibXML->new first!") unless ref $self; | ||||
863 | croak("parse already in progress") if $self->{_State_}; | ||||
864 | $self->{_State_} = 1; | ||||
865 | my $result; | ||||
866 | |||||
867 | $self->_init_callbacks(); | ||||
868 | |||||
869 | if ( defined $self->{SAX} ) { | ||||
870 | $self->{SAX_ELSTACK} = []; | ||||
871 | eval { $self->_parse_sax_fh( @_ ); }; | ||||
872 | my $err = $@; | ||||
873 | $self->{_State_} = 0; | ||||
874 | if ($err) { | ||||
875 | chomp $err unless ref $err; | ||||
876 | $self->_cleanup_callbacks(); | ||||
877 | croak $err; | ||||
878 | } | ||||
879 | } | ||||
880 | else { | ||||
881 | eval { $result = $self->_parse_fh( @_ ); }; | ||||
882 | my $err = $@; | ||||
883 | $self->{_State_} = 0; | ||||
884 | if ($err) { | ||||
885 | chomp $err unless ref $err; | ||||
886 | $self->_cleanup_callbacks(); | ||||
887 | croak $err; | ||||
888 | } | ||||
889 | |||||
890 | $result = $self->_auto_expand( $result, $self->{XML_LIBXML_BASE_URI} ); | ||||
891 | } | ||||
892 | |||||
893 | $self->_cleanup_callbacks(); | ||||
894 | |||||
895 | return $result; | ||||
896 | } | ||||
897 | |||||
898 | sub parse_file { | ||||
899 | my $self = shift; | ||||
900 | croak("parse_file is not a class method! Create a parser object with XML::LibXML->new first!") unless ref $self; | ||||
901 | croak("parse already in progress") if $self->{_State_}; | ||||
902 | |||||
903 | $self->{_State_} = 1; | ||||
904 | my $result; | ||||
905 | |||||
906 | $self->_init_callbacks(); | ||||
907 | |||||
908 | if ( defined $self->{SAX} ) { | ||||
909 | $self->{SAX_ELSTACK} = []; | ||||
910 | eval { $self->_parse_sax_file( @_ ); }; | ||||
911 | my $err = $@; | ||||
912 | $self->{_State_} = 0; | ||||
913 | if ($err) { | ||||
914 | chomp $err unless ref $err; | ||||
915 | $self->_cleanup_callbacks(); | ||||
916 | croak $err; | ||||
917 | } | ||||
918 | } | ||||
919 | else { | ||||
920 | eval { $result = $self->_parse_file(@_); }; | ||||
921 | my $err = $@; | ||||
922 | $self->{_State_} = 0; | ||||
923 | if ($err) { | ||||
924 | chomp $err unless ref $err; | ||||
925 | $self->_cleanup_callbacks(); | ||||
926 | croak $err; | ||||
927 | } | ||||
928 | |||||
929 | $result = $self->_auto_expand( $result ); | ||||
930 | } | ||||
931 | $self->_cleanup_callbacks(); | ||||
932 | |||||
933 | return $result; | ||||
934 | } | ||||
935 | |||||
936 | sub parse_xml_chunk { | ||||
937 | my $self = shift; | ||||
938 | # max 2 parameter: | ||||
939 | # 1: the chunk | ||||
940 | # 2: the encoding of the string | ||||
941 | croak("parse_xml_chunk is not a class method! Create a parser object with XML::LibXML->new first!") unless ref $self; | ||||
942 | croak("parse already in progress") if $self->{_State_}; my $result; | ||||
943 | |||||
944 | unless ( defined $_[0] and length $_[0] ) { | ||||
945 | croak("Empty String"); | ||||
946 | } | ||||
947 | |||||
948 | $self->{_State_} = 1; | ||||
949 | |||||
950 | $self->_init_callbacks(); | ||||
951 | |||||
952 | if ( defined $self->{SAX} ) { | ||||
953 | eval { | ||||
954 | $self->_parse_sax_xml_chunk( @_ ); | ||||
955 | |||||
956 | # this is required for XML::GenericChunk. | ||||
957 | # in normal case is_filter is not defined, an thus the parsing | ||||
958 | # will be terminated. in case of a SAX filter the parsing is not | ||||
959 | # finished at that state. therefore we must not reset the parsing | ||||
960 | unless ( $self->{IS_FILTER} ) { | ||||
961 | $result = $self->{HANDLER}->end_document(); | ||||
962 | } | ||||
963 | }; | ||||
964 | } | ||||
965 | else { | ||||
966 | eval { $result = $self->_parse_xml_chunk( @_ ); }; | ||||
967 | } | ||||
968 | |||||
969 | $self->_cleanup_callbacks(); | ||||
970 | |||||
971 | my $err = $@; | ||||
972 | $self->{_State_} = 0; | ||||
973 | if ($err) { | ||||
974 | chomp $err unless ref $err; | ||||
975 | croak $err; | ||||
976 | } | ||||
977 | |||||
978 | return $result; | ||||
979 | } | ||||
980 | |||||
981 | sub parse_balanced_chunk { | ||||
982 | my $self = shift; | ||||
983 | $self->_init_callbacks(); | ||||
984 | my $rv; | ||||
985 | eval { | ||||
986 | $rv = $self->parse_xml_chunk( @_ ); | ||||
987 | }; | ||||
988 | my $err = $@; | ||||
989 | $self->_cleanup_callbacks(); | ||||
990 | if ( $err ) { | ||||
991 | chomp $err unless ref $err; | ||||
992 | croak $err; | ||||
993 | } | ||||
994 | return $rv | ||||
995 | } | ||||
996 | |||||
997 | # java style | ||||
998 | sub processXIncludes { | ||||
999 | my $self = shift; | ||||
1000 | my $doc = shift; | ||||
1001 | my $opts = shift; | ||||
1002 | my $options = $self->_parser_options($opts); | ||||
1003 | if ( $self->{_State_} != 1 ) { | ||||
1004 | $self->_init_callbacks(); | ||||
1005 | } | ||||
1006 | my $rv; | ||||
1007 | eval { | ||||
1008 | $rv = $self->_processXIncludes($doc || " ", $options); | ||||
1009 | }; | ||||
1010 | my $err = $@; | ||||
1011 | if ( $self->{_State_} != 1 ) { | ||||
1012 | $self->_cleanup_callbacks(); | ||||
1013 | } | ||||
1014 | |||||
1015 | if ( $err ) { | ||||
1016 | chomp $err unless ref $err; | ||||
1017 | croak $err; | ||||
1018 | } | ||||
1019 | return $rv; | ||||
1020 | } | ||||
1021 | |||||
1022 | # perl style | ||||
1023 | sub process_xincludes { | ||||
1024 | my $self = shift; | ||||
1025 | my $doc = shift; | ||||
1026 | my $opts = shift; | ||||
1027 | my $options = $self->_parser_options($opts); | ||||
1028 | |||||
1029 | my $rv; | ||||
1030 | $self->_init_callbacks(); | ||||
1031 | eval { | ||||
1032 | $rv = $self->_processXIncludes($doc || " ", $options); | ||||
1033 | }; | ||||
1034 | my $err = $@; | ||||
1035 | $self->_cleanup_callbacks(); | ||||
1036 | if ( $err ) { | ||||
1037 | chomp $err unless ref $err; | ||||
1038 | croak $@; | ||||
1039 | } | ||||
1040 | return $rv; | ||||
1041 | } | ||||
1042 | |||||
1043 | #-------------------------------------------------------------------------# | ||||
1044 | # HTML parsing functions # | ||||
1045 | #-------------------------------------------------------------------------# | ||||
1046 | |||||
1047 | sub _html_options { | ||||
1048 | my ($self,$opts)=@_; | ||||
1049 | $opts = {} unless ref $opts; | ||||
1050 | # return (undef,undef) unless ref $opts; | ||||
1051 | my $flags = 0; | ||||
1052 | $flags |= 1 if exists $opts->{recover} ? $opts->{recover} : $self->recover; | ||||
1053 | $flags |= 4 if $opts->{no_defdtd}; # default is ON: injects DTD as needed | ||||
1054 | $flags |= 32 if exists $opts->{suppress_errors} ? $opts->{suppress_errors} : $self->get_option('suppress_errors'); | ||||
1055 | # This is to fix https://rt.cpan.org/Ticket/Display.html?id=58024 : | ||||
1056 | # <quote> | ||||
1057 | # In XML::LibXML, warnings are not suppressed when specifying the recover | ||||
1058 | # or recover_silently flags as per the following excerpt from the manpage: | ||||
1059 | # </quote> | ||||
1060 | if ($self->recover_silently) | ||||
1061 | { | ||||
1062 | $flags |= 32; | ||||
1063 | } | ||||
1064 | $flags |= 64 if $opts->{suppress_warnings}; | ||||
1065 | $flags |= 128 if exists $opts->{pedantic_parser} ? $opts->{pedantic_parser} : $self->pedantic_parser; | ||||
1066 | $flags |= 256 if exists $opts->{no_blanks} ? $opts->{no_blanks} : !$self->keep_blanks; | ||||
1067 | $flags |= 2048 if exists $opts->{no_network} ? $opts->{no_network} : !$self->no_network; | ||||
1068 | $flags |= 16384 if $opts->{no_cdata}; | ||||
1069 | $flags |= 65536 if $opts->{compact}; # compact small text nodes; no modification | ||||
1070 | # of the tree allowed afterwards | ||||
1071 | # (WILL possibly CRASH IF YOU try to MODIFY THE TREE) | ||||
1072 | $flags |= 524288 if $opts->{huge}; # relax any hardcoded limit from the parser | ||||
1073 | $flags |= 1048576 if $opts->{oldsax}; # parse using SAX2 interface from before 2.7.0 | ||||
1074 | |||||
1075 | return ($opts->{URI},$opts->{encoding},$flags); | ||||
1076 | } | ||||
1077 | |||||
1078 | sub parse_html_string { | ||||
1079 | my ($self,$str,$opts) = @_; | ||||
1080 | croak("parse_html_string is not a class method! Create a parser object with XML::LibXML->new first!") unless ref $self; | ||||
1081 | croak("parse already in progress") if $self->{_State_}; | ||||
1082 | |||||
1083 | unless ( defined $str and length $str ) { | ||||
1084 | croak("Empty String"); | ||||
1085 | } | ||||
1086 | $self->{_State_} = 1; | ||||
1087 | my $result; | ||||
1088 | |||||
1089 | $self->_init_callbacks(); | ||||
1090 | eval { | ||||
1091 | $result = $self->_parse_html_string( $str, | ||||
1092 | $self->_html_options($opts) | ||||
1093 | ); | ||||
1094 | }; | ||||
1095 | my $err = $@; | ||||
1096 | $self->{_State_} = 0; | ||||
1097 | if ($err) { | ||||
1098 | chomp $err unless ref $err; | ||||
1099 | $self->_cleanup_callbacks(); | ||||
1100 | croak $err; | ||||
1101 | } | ||||
1102 | |||||
1103 | $self->_cleanup_callbacks(); | ||||
1104 | |||||
1105 | return $result; | ||||
1106 | } | ||||
1107 | |||||
1108 | sub parse_html_file { | ||||
1109 | my ($self,$file,$opts) = @_; | ||||
1110 | croak("parse_html_file is not a class method! Create a parser object with XML::LibXML->new first!") unless ref $self; | ||||
1111 | croak("parse already in progress") if $self->{_State_}; | ||||
1112 | $self->{_State_} = 1; | ||||
1113 | my $result; | ||||
1114 | |||||
1115 | $self->_init_callbacks(); | ||||
1116 | eval { $result = $self->_parse_html_file($file, | ||||
1117 | $self->_html_options($opts) | ||||
1118 | ); }; | ||||
1119 | my $err = $@; | ||||
1120 | $self->{_State_} = 0; | ||||
1121 | if ($err) { | ||||
1122 | chomp $err unless ref $err; | ||||
1123 | $self->_cleanup_callbacks(); | ||||
1124 | croak $err; | ||||
1125 | } | ||||
1126 | |||||
1127 | $self->_cleanup_callbacks(); | ||||
1128 | |||||
1129 | return $result; | ||||
1130 | } | ||||
1131 | |||||
1132 | sub parse_html_fh { | ||||
1133 | my ($self,$fh,$opts) = @_; | ||||
1134 | croak("parse_html_fh is not a class method! Create a parser object with XML::LibXML->new first!") unless ref $self; | ||||
1135 | croak("parse already in progress") if $self->{_State_}; | ||||
1136 | $self->{_State_} = 1; | ||||
1137 | |||||
1138 | my $result; | ||||
1139 | $self->_init_callbacks(); | ||||
1140 | eval { $result = $self->_parse_html_fh( $fh, | ||||
1141 | $self->_html_options($opts) | ||||
1142 | ); }; | ||||
1143 | my $err = $@; | ||||
1144 | $self->{_State_} = 0; | ||||
1145 | if ($err) { | ||||
1146 | chomp $err unless ref $err; | ||||
1147 | $self->_cleanup_callbacks(); | ||||
1148 | croak $err; | ||||
1149 | } | ||||
1150 | $self->_cleanup_callbacks(); | ||||
1151 | |||||
1152 | return $result; | ||||
1153 | } | ||||
1154 | |||||
1155 | #-------------------------------------------------------------------------# | ||||
1156 | # push parser interface # | ||||
1157 | #-------------------------------------------------------------------------# | ||||
1158 | sub init_push { | ||||
1159 | my $self = shift; | ||||
1160 | |||||
1161 | if ( defined $self->{CONTEXT} ) { | ||||
1162 | delete $self->{CONTEXT}; | ||||
1163 | } | ||||
1164 | |||||
1165 | if ( defined $self->{SAX} ) { | ||||
1166 | $self->{CONTEXT} = $self->_start_push(1); | ||||
1167 | } | ||||
1168 | else { | ||||
1169 | $self->{CONTEXT} = $self->_start_push(0); | ||||
1170 | } | ||||
1171 | } | ||||
1172 | |||||
1173 | sub push { | ||||
1174 | my $self = shift; | ||||
1175 | |||||
1176 | $self->_init_callbacks(); | ||||
1177 | |||||
1178 | if ( not defined $self->{CONTEXT} ) { | ||||
1179 | $self->init_push(); | ||||
1180 | } | ||||
1181 | |||||
1182 | eval { | ||||
1183 | foreach ( @_ ) { | ||||
1184 | $self->_push( $self->{CONTEXT}, $_ ); | ||||
1185 | } | ||||
1186 | }; | ||||
1187 | my $err = $@; | ||||
1188 | $self->_cleanup_callbacks(); | ||||
1189 | if ( $err ) { | ||||
1190 | chomp $err unless ref $err; | ||||
1191 | croak $err; | ||||
1192 | } | ||||
1193 | } | ||||
1194 | |||||
1195 | # this function should be promoted! | ||||
1196 | # the reason is because libxml2 uses xmlParseChunk() for this purpose! | ||||
1197 | sub parse_chunk { | ||||
1198 | my $self = shift; | ||||
1199 | my $chunk = shift; | ||||
1200 | my $terminate = shift; | ||||
1201 | |||||
1202 | if ( not defined $self->{CONTEXT} ) { | ||||
1203 | $self->init_push(); | ||||
1204 | } | ||||
1205 | |||||
1206 | if ( defined $chunk and length $chunk ) { | ||||
1207 | $self->_push( $self->{CONTEXT}, $chunk ); | ||||
1208 | } | ||||
1209 | |||||
1210 | if ( $terminate ) { | ||||
1211 | return $self->finish_push(); | ||||
1212 | } | ||||
1213 | } | ||||
1214 | |||||
1215 | |||||
1216 | sub finish_push { | ||||
1217 | my $self = shift; | ||||
1218 | my $restore = shift || 0; | ||||
1219 | return undef unless defined $self->{CONTEXT}; | ||||
1220 | |||||
1221 | my $retval; | ||||
1222 | |||||
1223 | if ( defined $self->{SAX} ) { | ||||
1224 | eval { | ||||
1225 | $self->_end_sax_push( $self->{CONTEXT} ); | ||||
1226 | $retval = $self->{HANDLER}->end_document( {} ); | ||||
1227 | }; | ||||
1228 | } | ||||
1229 | else { | ||||
1230 | eval { $retval = $self->_end_push( $self->{CONTEXT}, $restore ); }; | ||||
1231 | } | ||||
1232 | my $err = $@; | ||||
1233 | delete $self->{CONTEXT}; | ||||
1234 | if ( $err ) { | ||||
1235 | chomp $err unless ref $err; | ||||
1236 | croak( $err ); | ||||
1237 | } | ||||
1238 | return $retval; | ||||
1239 | } | ||||
1240 | |||||
1241 | 1; | ||||
1242 | |||||
1243 | #-------------------------------------------------------------------------# | ||||
1244 | # XML::LibXML::Node Interface # | ||||
1245 | #-------------------------------------------------------------------------# | ||||
1246 | package XML::LibXML::Node; | ||||
1247 | |||||
1248 | sub CLONE_SKIP { | ||||
1249 | return $XML::LibXML::__threads_shared ? 0 : 1; | ||||
1250 | } | ||||
1251 | |||||
1252 | sub isSupported { | ||||
1253 | my $self = shift; | ||||
1254 | my $feature = shift; | ||||
1255 | return $self->can($feature) ? 1 : 0; | ||||
1256 | } | ||||
1257 | |||||
1258 | sub getChildNodes { my $self = shift; return $self->childNodes(); } | ||||
1259 | |||||
1260 | sub childNodes { | ||||
1261 | my $self = shift; | ||||
1262 | my @children = $self->_childNodes(0); | ||||
1263 | return wantarray ? @children : XML::LibXML::NodeList->new_from_ref(\@children , 1); | ||||
1264 | } | ||||
1265 | |||||
1266 | sub nonBlankChildNodes { | ||||
1267 | my $self = shift; | ||||
1268 | my @children = $self->_childNodes(1); | ||||
1269 | return wantarray ? @children : XML::LibXML::NodeList->new_from_ref(\@children , 1); | ||||
1270 | } | ||||
1271 | |||||
1272 | sub attributes { | ||||
1273 | my $self = shift; | ||||
1274 | my @attr = $self->_attributes(); | ||||
1275 | return wantarray ? @attr : XML::LibXML::NamedNodeMap->new( @attr ); | ||||
1276 | } | ||||
1277 | |||||
1278 | |||||
1279 | sub findnodes { | ||||
1280 | my ($node, $xpath) = @_; | ||||
1281 | my @nodes = $node->_findnodes($xpath); | ||||
1282 | if (wantarray) { | ||||
1283 | return @nodes; | ||||
1284 | } | ||||
1285 | else { | ||||
1286 | return XML::LibXML::NodeList->new_from_ref(\@nodes, 1); | ||||
1287 | } | ||||
1288 | } | ||||
1289 | |||||
1290 | sub exists { | ||||
1291 | my ($node, $xpath) = @_; | ||||
1292 | my (undef, $value) = $node->_find($xpath,1); | ||||
1293 | return $value; | ||||
1294 | } | ||||
1295 | |||||
1296 | sub findvalue { | ||||
1297 | my ($node, $xpath) = @_; | ||||
1298 | my $res; | ||||
1299 | $res = $node->find($xpath); | ||||
1300 | return $res->to_literal->value; | ||||
1301 | } | ||||
1302 | |||||
1303 | sub findbool { | ||||
1304 | my ($node, $xpath) = @_; | ||||
1305 | my ($type, @params) = $node->_find($xpath,1); | ||||
1306 | if ($type) { | ||||
1307 | return $type->new(@params); | ||||
1308 | } | ||||
1309 | return undef; | ||||
1310 | } | ||||
1311 | |||||
1312 | sub find { | ||||
1313 | my ($node, $xpath) = @_; | ||||
1314 | my ($type, @params) = $node->_find($xpath,0); | ||||
1315 | if ($type) { | ||||
1316 | return $type->new(@params); | ||||
1317 | } | ||||
1318 | return undef; | ||||
1319 | } | ||||
1320 | |||||
1321 | sub setOwnerDocument { | ||||
1322 | my ( $self, $doc ) = @_; | ||||
1323 | $doc->adoptNode( $self ); | ||||
1324 | } | ||||
1325 | |||||
1326 | sub toStringC14N { | ||||
1327 | my ($self, $comments, $xpath, $xpc) = @_; | ||||
1328 | return $self->_toStringC14N( $comments || 0, | ||||
1329 | (defined $xpath ? $xpath : undef), | ||||
1330 | 0, | ||||
1331 | undef, | ||||
1332 | (defined $xpc ? $xpc : undef) | ||||
1333 | ); | ||||
1334 | } | ||||
1335 | sub toStringEC14N { | ||||
1336 | my ($self, $comments, $xpath, $xpc, $inc_prefix_list) = @_; | ||||
1337 | unless (UNIVERSAL::isa($xpc,'XML::LibXML::XPathContext')) { | ||||
1338 | if ($inc_prefix_list) { | ||||
1339 | croak("toStringEC14N: 3rd argument is not an XML::LibXML::XPathContext"); | ||||
1340 | } else { | ||||
1341 | $inc_prefix_list=$xpc; | ||||
1342 | $xpc=undef; | ||||
1343 | } | ||||
1344 | } | ||||
1345 | if (defined($inc_prefix_list) and !UNIVERSAL::isa($inc_prefix_list,'ARRAY')) { | ||||
1346 | croak("toStringEC14N: inclusive_prefix_list must be undefined or ARRAY"); | ||||
1347 | } | ||||
1348 | return $self->_toStringC14N( $comments || 0, | ||||
1349 | (defined $xpath ? $xpath : undef), | ||||
1350 | 1, | ||||
1351 | (defined $inc_prefix_list ? $inc_prefix_list : undef), | ||||
1352 | (defined $xpc ? $xpc : undef) | ||||
1353 | ); | ||||
1354 | } | ||||
1355 | |||||
1356 | 1 | 10µs | *serialize_c14n = \&toStringC14N; | ||
1357 | 1 | 3µs | *serialize_exc_c14n = \&toStringEC14N; | ||
1358 | |||||
1359 | 1; | ||||
1360 | |||||
1361 | #-------------------------------------------------------------------------# | ||||
1362 | # XML::LibXML::Document Interface # | ||||
1363 | #-------------------------------------------------------------------------# | ||||
1364 | package XML::LibXML::Document; | ||||
1365 | |||||
1366 | 2 | 2.37ms | 2 | 443µs | # spent 256µs (68+187) within XML::LibXML::Document::BEGIN@1366 which was called:
# once (68µs+187µs) by XML::LibXML::SAX::BEGIN@17 at line 1366 # spent 256µs making 1 call to XML::LibXML::Document::BEGIN@1366
# spent 187µs making 1 call to vars::import |
1367 | 1 | 44µs | @ISA = ('XML::LibXML::Node'); | ||
1368 | |||||
1369 | sub actualEncoding { | ||||
1370 | my $doc = shift; | ||||
1371 | my $enc = $doc->encoding; | ||||
1372 | return (defined $enc and length $enc) ? $enc : 'UTF-8'; | ||||
1373 | } | ||||
1374 | |||||
1375 | sub setDocumentElement { | ||||
1376 | my $doc = shift; | ||||
1377 | my $element = shift; | ||||
1378 | |||||
1379 | my $oldelem = $doc->documentElement; | ||||
1380 | if ( defined $oldelem ) { | ||||
1381 | $doc->removeChild($oldelem); | ||||
1382 | } | ||||
1383 | |||||
1384 | $doc->_setDocumentElement($element); | ||||
1385 | } | ||||
1386 | |||||
1387 | sub toString { | ||||
1388 | my $self = shift; | ||||
1389 | my $flag = shift; | ||||
1390 | |||||
1391 | my $retval = ""; | ||||
1392 | |||||
1393 | if ( defined $XML::LibXML::skipXMLDeclaration | ||||
1394 | and $XML::LibXML::skipXMLDeclaration == 1 ) { | ||||
1395 | foreach ( $self->childNodes ){ | ||||
1396 | next if $_->nodeType == XML::LibXML::XML_DTD_NODE() | ||||
1397 | and $XML::LibXML::skipDTD; | ||||
1398 | $retval .= $_->toString; | ||||
1399 | } | ||||
1400 | } | ||||
1401 | else { | ||||
1402 | $flag ||= 0 unless defined $flag; | ||||
1403 | $retval = $self->_toString($flag); | ||||
1404 | } | ||||
1405 | |||||
1406 | return $retval; | ||||
1407 | } | ||||
1408 | |||||
1409 | sub serialize { | ||||
1410 | my $self = shift; | ||||
1411 | return $self->toString( @_ ); | ||||
1412 | } | ||||
1413 | |||||
1414 | #-------------------------------------------------------------------------# | ||||
1415 | # bad style xinclude processing # | ||||
1416 | #-------------------------------------------------------------------------# | ||||
1417 | sub process_xinclude { | ||||
1418 | my $self = shift; | ||||
1419 | my $opts = shift; | ||||
1420 | XML::LibXML->new->processXIncludes( $self, $opts ); | ||||
1421 | } | ||||
1422 | |||||
1423 | sub insertProcessingInstruction { | ||||
1424 | my $self = shift; | ||||
1425 | my $target = shift; | ||||
1426 | my $data = shift; | ||||
1427 | |||||
1428 | my $pi = $self->createPI( $target, $data ); | ||||
1429 | my $root = $self->documentElement; | ||||
1430 | |||||
1431 | if ( defined $root ) { | ||||
1432 | # this is actually not correct, but i guess it's what the user | ||||
1433 | # intends | ||||
1434 | $self->insertBefore( $pi, $root ); | ||||
1435 | } | ||||
1436 | else { | ||||
1437 | # if no documentElement was found we just append the PI | ||||
1438 | $self->appendChild( $pi ); | ||||
1439 | } | ||||
1440 | } | ||||
1441 | |||||
1442 | sub insertPI { | ||||
1443 | my $self = shift; | ||||
1444 | $self->insertProcessingInstruction( @_ ); | ||||
1445 | } | ||||
1446 | |||||
1447 | #-------------------------------------------------------------------------# | ||||
1448 | # DOM L3 Document functions. | ||||
1449 | # added after robins implicit feature requst | ||||
1450 | #-------------------------------------------------------------------------# | ||||
1451 | 1 | 7µs | *getElementsByTagName = \&XML::LibXML::Element::getElementsByTagName; | ||
1452 | 1 | 3µs | *getElementsByTagNameNS = \&XML::LibXML::Element::getElementsByTagNameNS; | ||
1453 | 1 | 2µs | *getElementsByLocalName = \&XML::LibXML::Element::getElementsByLocalName; | ||
1454 | |||||
1455 | 1; | ||||
1456 | |||||
1457 | #-------------------------------------------------------------------------# | ||||
1458 | # XML::LibXML::DocumentFragment Interface # | ||||
1459 | #-------------------------------------------------------------------------# | ||||
1460 | package XML::LibXML::DocumentFragment; | ||||
1461 | |||||
1462 | 2 | 650µs | 2 | 377µs | # spent 218µs (60+158) within XML::LibXML::DocumentFragment::BEGIN@1462 which was called:
# once (60µs+158µs) by XML::LibXML::SAX::BEGIN@17 at line 1462 # spent 218µs making 1 call to XML::LibXML::DocumentFragment::BEGIN@1462
# spent 158µs making 1 call to vars::import |
1463 | 1 | 24µs | @ISA = ('XML::LibXML::Node'); | ||
1464 | |||||
1465 | sub toString { | ||||
1466 | my $self = shift; | ||||
1467 | my $retval = ""; | ||||
1468 | if ( $self->hasChildNodes() ) { | ||||
1469 | foreach my $n ( $self->childNodes() ) { | ||||
1470 | $retval .= $n->toString(@_); | ||||
1471 | } | ||||
1472 | } | ||||
1473 | return $retval; | ||||
1474 | } | ||||
1475 | |||||
1476 | 1 | 5µs | *serialize = \&toString; | ||
1477 | |||||
1478 | 1; | ||||
1479 | |||||
1480 | #-------------------------------------------------------------------------# | ||||
1481 | # XML::LibXML::Element Interface # | ||||
1482 | #-------------------------------------------------------------------------# | ||||
1483 | package XML::LibXML::Element; | ||||
1484 | |||||
1485 | 2 | 206µs | 2 | 330µs | # spent 194µs (58+136) within XML::LibXML::Element::BEGIN@1485 which was called:
# once (58µs+136µs) by XML::LibXML::SAX::BEGIN@17 at line 1485 # spent 194µs making 1 call to XML::LibXML::Element::BEGIN@1485
# spent 136µs making 1 call to vars::import |
1486 | 1 | 22µs | @ISA = ('XML::LibXML::Node'); | ||
1487 | 2 | 226µs | 2 | 4.72ms | # spent 2.39ms (54µs+2.33) within XML::LibXML::Element::BEGIN@1487 which was called:
# once (54µs+2.33ms) by XML::LibXML::SAX::BEGIN@17 at line 1487 # spent 2.39ms making 1 call to XML::LibXML::Element::BEGIN@1487
# spent 2.33ms making 1 call to XML::LibXML::import |
1488 | 2 | 5.63ms | 2 | 563µs | # spent 313µs (64+250) within XML::LibXML::Element::BEGIN@1488 which was called:
# once (64µs+250µs) by XML::LibXML::SAX::BEGIN@17 at line 1488 # spent 313µs making 1 call to XML::LibXML::Element::BEGIN@1488
# spent 250µs making 1 call to Exporter::import |
1489 | |||||
1490 | sub setNamespace { | ||||
1491 | my $self = shift; | ||||
1492 | my $n = $self->nodeName; | ||||
1493 | if ( $self->_setNamespace(@_) ){ | ||||
1494 | if ( scalar @_ < 3 || $_[2] == 1 ){ | ||||
1495 | $self->setNodeName( $n ); | ||||
1496 | } | ||||
1497 | return 1; | ||||
1498 | } | ||||
1499 | return 0; | ||||
1500 | } | ||||
1501 | |||||
1502 | sub getAttribute { | ||||
1503 | my $self = shift; | ||||
1504 | my $name = $_[0]; | ||||
1505 | if ( $name =~ /^xmlns(?::|$)/ ) { | ||||
1506 | # user wants to get a namespace ... | ||||
1507 | (my $prefix = $name )=~s/^xmlns:?//; | ||||
1508 | $self->_getNamespaceDeclURI($prefix); | ||||
1509 | } | ||||
1510 | else { | ||||
1511 | $self->_getAttribute(@_); | ||||
1512 | } | ||||
1513 | } | ||||
1514 | |||||
1515 | sub setAttribute { | ||||
1516 | my ( $self, $name, $value ) = @_; | ||||
1517 | if ( $name =~ /^xmlns(?::|$)/ ) { | ||||
1518 | # user wants to set the special attribute for declaring XML namespace ... | ||||
1519 | |||||
1520 | # this is fine but not exactly DOM conformant behavior, btw (according to DOM we should | ||||
1521 | # probably declare an attribute which looks like XML namespace declaration | ||||
1522 | # but isn't) | ||||
1523 | (my $nsprefix = $name )=~s/^xmlns:?//; | ||||
1524 | my $nn = $self->nodeName; | ||||
1525 | if ( $nn =~ /^\Q${nsprefix}\E:/ ) { | ||||
1526 | # the element has the same prefix | ||||
1527 | $self->setNamespaceDeclURI($nsprefix,$value) || | ||||
1528 | $self->setNamespace($value,$nsprefix,1); | ||||
1529 | ## | ||||
1530 | ## We set the namespace here. | ||||
1531 | ## This is helpful, as in: | ||||
1532 | ## | ||||
1533 | ## | $e = XML::LibXML::Element->new('foo:bar'); | ||||
1534 | ## | $e->setAttribute('xmlns:foo','http://yoyodine') | ||||
1535 | ## | ||||
1536 | } | ||||
1537 | else { | ||||
1538 | # just modify the namespace | ||||
1539 | $self->setNamespaceDeclURI($nsprefix, $value) || | ||||
1540 | $self->setNamespace($value,$nsprefix,0); | ||||
1541 | } | ||||
1542 | } | ||||
1543 | else { | ||||
1544 | $self->_setAttribute($name, $value); | ||||
1545 | } | ||||
1546 | } | ||||
1547 | |||||
1548 | sub getAttributeNS { | ||||
1549 | my $self = shift; | ||||
1550 | my ($nsURI, $name) = @_; | ||||
1551 | croak("invalid attribute name") if !defined($name) or $name eq q{}; | ||||
1552 | if ( defined($nsURI) and $nsURI eq XML_XMLNS_NS ) { | ||||
1553 | $self->_getNamespaceDeclURI($name eq 'xmlns' ? undef : $name); | ||||
1554 | } | ||||
1555 | else { | ||||
1556 | $self->_getAttributeNS(@_); | ||||
1557 | } | ||||
1558 | } | ||||
1559 | |||||
1560 | sub setAttributeNS { | ||||
1561 | my ($self, $nsURI, $qname, $value)=@_; | ||||
1562 | unless (defined $qname and length $qname) { | ||||
1563 | croak("bad name"); | ||||
1564 | } | ||||
1565 | if (defined($nsURI) and $nsURI eq XML_XMLNS_NS) { | ||||
1566 | if ($qname !~ /^xmlns(?::|$)/) { | ||||
1567 | croak("NAMESPACE ERROR: Namespace declarations must have the prefix 'xmlns'"); | ||||
1568 | } | ||||
1569 | $self->setAttribute($qname,$value); # see implementation above | ||||
1570 | return; | ||||
1571 | } | ||||
1572 | if ($qname=~/:/ and not (defined($nsURI) and length($nsURI))) { | ||||
1573 | croak("NAMESPACE ERROR: Attribute without a prefix cannot be in a namespace"); | ||||
1574 | } | ||||
1575 | if ($qname=~/^xmlns(?:$|:)/) { | ||||
1576 | croak("NAMESPACE ERROR: 'xmlns' prefix and qualified-name are reserved for the namespace ".XML_XMLNS_NS); | ||||
1577 | } | ||||
1578 | if ($qname=~/^xml:/ and not (defined $nsURI and $nsURI eq XML_XML_NS)) { | ||||
1579 | croak("NAMESPACE ERROR: 'xml' prefix is reserved for the namespace ".XML_XML_NS); | ||||
1580 | } | ||||
1581 | $self->_setAttributeNS( defined $nsURI ? $nsURI : undef, $qname, $value ); | ||||
1582 | } | ||||
1583 | |||||
1584 | sub getElementsByTagName { | ||||
1585 | my ( $node , $name ) = @_; | ||||
1586 | my $xpath = $name eq '*' ? "descendant::*" : "descendant::*[name()='$name']"; | ||||
1587 | my @nodes = $node->_findnodes($xpath); | ||||
1588 | return wantarray ? @nodes : XML::LibXML::NodeList->new_from_ref(\@nodes, 1); | ||||
1589 | } | ||||
1590 | |||||
1591 | sub getElementsByTagNameNS { | ||||
1592 | my ( $node, $nsURI, $name ) = @_; | ||||
1593 | my $xpath; | ||||
1594 | if ( $name eq '*' ) { | ||||
1595 | if ( $nsURI eq '*' ) { | ||||
1596 | $xpath = "descendant::*"; | ||||
1597 | } else { | ||||
1598 | $xpath = "descendant::*[namespace-uri()='$nsURI']"; | ||||
1599 | } | ||||
1600 | } elsif ( $nsURI eq '*' ) { | ||||
1601 | $xpath = "descendant::*[local-name()='$name']"; | ||||
1602 | } else { | ||||
1603 | $xpath = "descendant::*[local-name()='$name' and namespace-uri()='$nsURI']"; | ||||
1604 | } | ||||
1605 | my @nodes = $node->_findnodes($xpath); | ||||
1606 | return wantarray ? @nodes : XML::LibXML::NodeList->new_from_ref(\@nodes, 1); | ||||
1607 | } | ||||
1608 | |||||
1609 | sub getElementsByLocalName { | ||||
1610 | my ( $node,$name ) = @_; | ||||
1611 | my $xpath; | ||||
1612 | if ($name eq '*') { | ||||
1613 | $xpath = "descendant::*"; | ||||
1614 | } else { | ||||
1615 | $xpath = "descendant::*[local-name()='$name']"; | ||||
1616 | } | ||||
1617 | my @nodes = $node->_findnodes($xpath); | ||||
1618 | return wantarray ? @nodes : XML::LibXML::NodeList->new_from_ref(\@nodes, 1); | ||||
1619 | } | ||||
1620 | |||||
1621 | sub getChildrenByTagName { | ||||
1622 | my ( $node, $name ) = @_; | ||||
1623 | my @nodes; | ||||
1624 | if ($name eq '*') { | ||||
1625 | @nodes = grep { $_->nodeType == XML_ELEMENT_NODE() } | ||||
1626 | $node->childNodes(); | ||||
1627 | } else { | ||||
1628 | @nodes = grep { $_->nodeName eq $name } $node->childNodes(); | ||||
1629 | } | ||||
1630 | return wantarray ? @nodes : XML::LibXML::NodeList->new_from_ref(\@nodes, 1); | ||||
1631 | } | ||||
1632 | |||||
1633 | sub getChildrenByLocalName { | ||||
1634 | my ( $node, $name ) = @_; | ||||
1635 | # my @nodes; | ||||
1636 | # if ($name eq '*') { | ||||
1637 | # @nodes = grep { $_->nodeType == XML_ELEMENT_NODE() } | ||||
1638 | # $node->childNodes(); | ||||
1639 | # } else { | ||||
1640 | # @nodes = grep { $_->nodeType == XML_ELEMENT_NODE() and | ||||
1641 | # $_->localName eq $name } $node->childNodes(); | ||||
1642 | # } | ||||
1643 | # return wantarray ? @nodes : XML::LibXML::NodeList->new_from_ref(\@nodes, 1); | ||||
1644 | my @nodes = $node->_getChildrenByTagNameNS('*',$name); | ||||
1645 | return wantarray ? @nodes : XML::LibXML::NodeList->new_from_ref(\@nodes, 1); | ||||
1646 | } | ||||
1647 | |||||
1648 | sub getChildrenByTagNameNS { | ||||
1649 | my ( $node, $nsURI, $name ) = @_; | ||||
1650 | my @nodes = $node->_getChildrenByTagNameNS($nsURI,$name); | ||||
1651 | return wantarray ? @nodes : XML::LibXML::NodeList->new_from_ref(\@nodes, 1); | ||||
1652 | } | ||||
1653 | |||||
1654 | sub appendWellBalancedChunk { | ||||
1655 | my ( $self, $chunk ) = @_; | ||||
1656 | |||||
1657 | my $local_parser = XML::LibXML->new(); | ||||
1658 | my $frag = $local_parser->parse_xml_chunk( $chunk ); | ||||
1659 | |||||
1660 | $self->appendChild( $frag ); | ||||
1661 | } | ||||
1662 | |||||
1663 | 1; | ||||
1664 | |||||
1665 | #-------------------------------------------------------------------------# | ||||
1666 | # XML::LibXML::Text Interface # | ||||
1667 | #-------------------------------------------------------------------------# | ||||
1668 | package XML::LibXML::Text; | ||||
1669 | |||||
1670 | 2 | 1.39ms | 2 | 431µs | # spent 248µs (65+183) within XML::LibXML::Text::BEGIN@1670 which was called:
# once (65µs+183µs) by XML::LibXML::SAX::BEGIN@17 at line 1670 # spent 248µs making 1 call to XML::LibXML::Text::BEGIN@1670
# spent 183µs making 1 call to vars::import |
1671 | 1 | 21µs | @ISA = ('XML::LibXML::Node'); | ||
1672 | |||||
1673 | sub attributes { return undef; } | ||||
1674 | |||||
1675 | sub deleteDataString { | ||||
1676 | my ($node, $string, $all) = @_; | ||||
1677 | |||||
1678 | return $node->replaceDataString($string, '', $all); | ||||
1679 | } | ||||
1680 | |||||
1681 | sub replaceDataString { | ||||
1682 | my ( $node, $left_proto, $right,$all ) = @_; | ||||
1683 | |||||
1684 | # Assure we exchange the strings and not expressions! | ||||
1685 | my $left = quotemeta($left_proto); | ||||
1686 | |||||
1687 | my $datastr = $node->nodeValue(); | ||||
1688 | if ( $all ) { | ||||
1689 | $datastr =~ s/$left/$right/g; | ||||
1690 | } | ||||
1691 | else{ | ||||
1692 | $datastr =~ s/$left/$right/; | ||||
1693 | } | ||||
1694 | $node->setData( $datastr ); | ||||
1695 | } | ||||
1696 | |||||
1697 | sub replaceDataRegEx { | ||||
1698 | my ( $node, $leftre, $rightre, $flags ) = @_; | ||||
1699 | return unless defined $leftre; | ||||
1700 | $rightre ||= ""; | ||||
1701 | |||||
1702 | my $datastr = $node->nodeValue(); | ||||
1703 | my $restr = "s/" . $leftre . "/" . $rightre . "/"; | ||||
1704 | $restr .= $flags if defined $flags; | ||||
1705 | |||||
1706 | eval '$datastr =~ '. $restr; | ||||
1707 | |||||
1708 | $node->setData( $datastr ); | ||||
1709 | } | ||||
1710 | |||||
1711 | 1; | ||||
1712 | |||||
1713 | package XML::LibXML::Comment; | ||||
1714 | |||||
1715 | 2 | 251µs | 2 | 376µs | # spent 226µs (76+150) within XML::LibXML::Comment::BEGIN@1715 which was called:
# once (76µs+150µs) by XML::LibXML::SAX::BEGIN@17 at line 1715 # spent 226µs making 1 call to XML::LibXML::Comment::BEGIN@1715
# spent 150µs making 1 call to vars::import |
1716 | 1 | 23µs | @ISA = ('XML::LibXML::Text'); | ||
1717 | |||||
1718 | 1; | ||||
1719 | |||||
1720 | package XML::LibXML::CDATASection; | ||||
1721 | |||||
1722 | 2 | 244µs | 2 | 315µs | # spent 191µs (68+123) within XML::LibXML::CDATASection::BEGIN@1722 which was called:
# once (68µs+123µs) by XML::LibXML::SAX::BEGIN@17 at line 1722 # spent 191µs making 1 call to XML::LibXML::CDATASection::BEGIN@1722
# spent 123µs making 1 call to vars::import |
1723 | 1 | 62µs | @ISA = ('XML::LibXML::Text'); | ||
1724 | |||||
1725 | 1; | ||||
1726 | |||||
1727 | #-------------------------------------------------------------------------# | ||||
1728 | # XML::LibXML::Attribute Interface # | ||||
1729 | #-------------------------------------------------------------------------# | ||||
1730 | package XML::LibXML::Attr; | ||||
1731 | 2 | 526µs | 2 | 310µs | # spent 187µs (64+123) within XML::LibXML::Attr::BEGIN@1731 which was called:
# once (64µs+123µs) by XML::LibXML::SAX::BEGIN@17 at line 1731 # spent 187µs making 1 call to XML::LibXML::Attr::BEGIN@1731
# spent 123µs making 1 call to vars::import |
1732 | 1 | 22µs | @ISA = ('XML::LibXML::Node') ; | ||
1733 | |||||
1734 | sub setNamespace { | ||||
1735 | my ($self,$href,$prefix) = @_; | ||||
1736 | my $n = $self->nodeName; | ||||
1737 | if ( $self->_setNamespace($href,$prefix) ) { | ||||
1738 | $self->setNodeName($n); | ||||
1739 | return 1; | ||||
1740 | } | ||||
1741 | |||||
1742 | return 0; | ||||
1743 | } | ||||
1744 | |||||
1745 | 1; | ||||
1746 | |||||
1747 | #-------------------------------------------------------------------------# | ||||
1748 | # XML::LibXML::Dtd Interface # | ||||
1749 | #-------------------------------------------------------------------------# | ||||
1750 | # this is still under construction | ||||
1751 | # | ||||
1752 | package XML::LibXML::Dtd; | ||||
1753 | 2 | 265µs | 2 | 336µs | # spent 206µs (76+130) within XML::LibXML::Dtd::BEGIN@1753 which was called:
# once (76µs+130µs) by XML::LibXML::SAX::BEGIN@17 at line 1753 # spent 206µs making 1 call to XML::LibXML::Dtd::BEGIN@1753
# spent 130µs making 1 call to vars::import |
1754 | 1 | 22µs | @ISA = ('XML::LibXML::Node'); | ||
1755 | |||||
1756 | # at least DESTROY and CLONE_SKIP must be inherited | ||||
1757 | |||||
1758 | 1; | ||||
1759 | |||||
1760 | #-------------------------------------------------------------------------# | ||||
1761 | # XML::LibXML::PI Interface # | ||||
1762 | #-------------------------------------------------------------------------# | ||||
1763 | package XML::LibXML::PI; | ||||
1764 | 2 | 2.04ms | 2 | 306µs | # spent 184µs (63+121) within XML::LibXML::PI::BEGIN@1764 which was called:
# once (63µs+121µs) by XML::LibXML::SAX::BEGIN@17 at line 1764 # spent 184µs making 1 call to XML::LibXML::PI::BEGIN@1764
# spent 121µs making 1 call to vars::import |
1765 | 1 | 20µs | @ISA = ('XML::LibXML::Node'); | ||
1766 | |||||
1767 | sub setData { | ||||
1768 | my $pi = shift; | ||||
1769 | |||||
1770 | my $string = ""; | ||||
1771 | if ( scalar @_ == 1 ) { | ||||
1772 | $string = shift; | ||||
1773 | } | ||||
1774 | else { | ||||
1775 | my %h = @_; | ||||
1776 | $string = join " ", map {$_.'="'.$h{$_}.'"'} keys %h; | ||||
1777 | } | ||||
1778 | |||||
1779 | # the spec says any char but "?>" [17] | ||||
1780 | $pi->_setData( $string ) unless $string =~ /\?>/; | ||||
1781 | } | ||||
1782 | |||||
1783 | 1; | ||||
1784 | |||||
1785 | #-------------------------------------------------------------------------# | ||||
1786 | # XML::LibXML::Namespace Interface # | ||||
1787 | #-------------------------------------------------------------------------# | ||||
1788 | package XML::LibXML::Namespace; | ||||
1789 | |||||
1790 | sub CLONE_SKIP { 1 } | ||||
1791 | |||||
1792 | # this is infact not a node! | ||||
1793 | sub prefix { return "xmlns"; } | ||||
1794 | sub getPrefix { return "xmlns"; } | ||||
1795 | sub getNamespaceURI { return "http://www.w3.org/2000/xmlns/" }; | ||||
1796 | |||||
1797 | sub getNamespaces { return (); } | ||||
1798 | |||||
1799 | sub nodeName { | ||||
1800 | my $self = shift; | ||||
1801 | my $nsP = $self->localname; | ||||
1802 | return ( defined($nsP) && length($nsP) ) ? "xmlns:$nsP" : "xmlns"; | ||||
1803 | } | ||||
1804 | sub name { goto &nodeName } | ||||
1805 | sub getName { goto &nodeName } | ||||
1806 | |||||
1807 | sub isEqualNode { | ||||
1808 | my ( $self, $ref ) = @_; | ||||
1809 | if ( ref($ref) eq "XML::LibXML::Namespace" ) { | ||||
1810 | return $self->_isEqual($ref); | ||||
1811 | } | ||||
1812 | return 0; | ||||
1813 | } | ||||
1814 | |||||
1815 | sub isSameNode { | ||||
1816 | my ( $self, $ref ) = @_; | ||||
1817 | if ( $$self == $$ref ){ | ||||
1818 | return 1; | ||||
1819 | } | ||||
1820 | return 0; | ||||
1821 | } | ||||
1822 | |||||
1823 | 1 | 400ns | 1; | ||
1824 | |||||
1825 | #-------------------------------------------------------------------------# | ||||
1826 | # XML::LibXML::NamedNodeMap Interface # | ||||
1827 | #-------------------------------------------------------------------------# | ||||
1828 | package XML::LibXML::NamedNodeMap; | ||||
1829 | |||||
1830 | 2 | 2.96ms | 2 | 2.79ms | # spent 1.43ms (63µs+1.36) within XML::LibXML::NamedNodeMap::BEGIN@1830 which was called:
# once (63µs+1.36ms) by XML::LibXML::SAX::BEGIN@17 at line 1830 # spent 1.43ms making 1 call to XML::LibXML::NamedNodeMap::BEGIN@1830
# spent 1.36ms making 1 call to XML::LibXML::import |
1831 | |||||
1832 | sub CLONE_SKIP { | ||||
1833 | return $XML::LibXML::__threads_shared ? 0 : 1; | ||||
1834 | } | ||||
1835 | |||||
1836 | sub new { | ||||
1837 | my $class = shift; | ||||
1838 | my $self = bless { Nodes => [@_] }, $class; | ||||
1839 | $self->{NodeMap} = { map { $_->nodeName => $_ } @_ }; | ||||
1840 | return $self; | ||||
1841 | } | ||||
1842 | |||||
1843 | sub length { return scalar( @{$_[0]->{Nodes}} ); } | ||||
1844 | sub nodes { return $_[0]->{Nodes}; } | ||||
1845 | sub item { $_[0]->{Nodes}->[$_[1]]; } | ||||
1846 | |||||
1847 | sub getNamedItem { | ||||
1848 | my $self = shift; | ||||
1849 | my $name = shift; | ||||
1850 | |||||
1851 | return $self->{NodeMap}->{$name}; | ||||
1852 | } | ||||
1853 | |||||
1854 | sub setNamedItem { | ||||
1855 | my $self = shift; | ||||
1856 | my $node = shift; | ||||
1857 | |||||
1858 | my $retval; | ||||
1859 | if ( defined $node ) { | ||||
1860 | if ( scalar @{$self->{Nodes}} ) { | ||||
1861 | my $name = $node->nodeName(); | ||||
1862 | if ( $node->nodeType() == XML_NAMESPACE_DECL ) { | ||||
1863 | return; | ||||
1864 | } | ||||
1865 | if ( defined $self->{NodeMap}->{$name} ) { | ||||
1866 | if ( $node->isSameNode( $self->{NodeMap}->{$name} ) ) { | ||||
1867 | return; | ||||
1868 | } | ||||
1869 | $retval = $self->{NodeMap}->{$name}->replaceNode( $node ); | ||||
1870 | } | ||||
1871 | else { | ||||
1872 | $self->{Nodes}->[0]->addSibling($node); | ||||
1873 | } | ||||
1874 | |||||
1875 | $self->{NodeMap}->{$name} = $node; | ||||
1876 | push @{$self->{Nodes}}, $node; | ||||
1877 | } | ||||
1878 | else { | ||||
1879 | # not done yet | ||||
1880 | # can this be properly be done??? | ||||
1881 | warn "not done yet\n"; | ||||
1882 | } | ||||
1883 | } | ||||
1884 | return $retval; | ||||
1885 | } | ||||
1886 | |||||
1887 | sub removeNamedItem { | ||||
1888 | my $self = shift; | ||||
1889 | my $name = shift; | ||||
1890 | my $retval; | ||||
1891 | if ( $name =~ /^xmlns/ ) { | ||||
1892 | warn "not done yet\n"; | ||||
1893 | } | ||||
1894 | elsif ( exists $self->{NodeMap}->{$name} ) { | ||||
1895 | $retval = $self->{NodeMap}->{$name}; | ||||
1896 | $retval->unbindNode; | ||||
1897 | delete $self->{NodeMap}->{$name}; | ||||
1898 | $self->{Nodes} = [grep {not($retval->isSameNode($_))} @{$self->{Nodes}}]; | ||||
1899 | } | ||||
1900 | |||||
1901 | return $retval; | ||||
1902 | } | ||||
1903 | |||||
1904 | sub getNamedItemNS { | ||||
1905 | my $self = shift; | ||||
1906 | my $nsURI = shift; | ||||
1907 | my $name = shift; | ||||
1908 | return undef; | ||||
1909 | } | ||||
1910 | |||||
1911 | sub setNamedItemNS { | ||||
1912 | my $self = shift; | ||||
1913 | my $nsURI = shift; | ||||
1914 | my $node = shift; | ||||
1915 | return undef; | ||||
1916 | } | ||||
1917 | |||||
1918 | sub removeNamedItemNS { | ||||
1919 | my $self = shift; | ||||
1920 | my $nsURI = shift; | ||||
1921 | my $name = shift; | ||||
1922 | return undef; | ||||
1923 | } | ||||
1924 | |||||
1925 | 1; | ||||
1926 | |||||
1927 | package XML::LibXML::_SAXParser; | ||||
1928 | |||||
1929 | # this is pseudo class!!! and it will be removed as soon all functions | ||||
1930 | # moved to XS level | ||||
1931 | |||||
1932 | 2 | 3.50ms | 1 | 44µs | # spent 44µs within XML::LibXML::_SAXParser::BEGIN@1932 which was called:
# once (44µs+0s) by XML::LibXML::SAX::BEGIN@17 at line 1932 # spent 44µs making 1 call to XML::LibXML::_SAXParser::BEGIN@1932 |
1933 | |||||
1934 | sub CLONE_SKIP { | ||||
1935 | return $XML::LibXML::__threads_shared ? 0 : 1; | ||||
1936 | } | ||||
1937 | |||||
1938 | # these functions will use SAX exceptions as soon i know how things really work | ||||
1939 | sub warning { | ||||
1940 | my ( $parser, $message, $line, $col ) = @_; | ||||
1941 | my $error = XML::SAX::Exception::Parse->new( LineNumber => $line, | ||||
1942 | ColumnNumber => $col, | ||||
1943 | Message => $message, ); | ||||
1944 | $parser->{HANDLER}->warning( $error ); | ||||
1945 | } | ||||
1946 | |||||
1947 | sub error { | ||||
1948 | my ( $parser, $message, $line, $col ) = @_; | ||||
1949 | |||||
1950 | my $error = XML::SAX::Exception::Parse->new( LineNumber => $line, | ||||
1951 | ColumnNumber => $col, | ||||
1952 | Message => $message, ); | ||||
1953 | $parser->{HANDLER}->error( $error ); | ||||
1954 | } | ||||
1955 | |||||
1956 | sub fatal_error { | ||||
1957 | my ( $parser, $message, $line, $col ) = @_; | ||||
1958 | my $error = XML::SAX::Exception::Parse->new( LineNumber => $line, | ||||
1959 | ColumnNumber => $col, | ||||
1960 | Message => $message, ); | ||||
1961 | $parser->{HANDLER}->fatal_error( $error ); | ||||
1962 | } | ||||
1963 | |||||
1964 | 1 | 300ns | 1; | ||
1965 | |||||
1966 | package XML::LibXML::RelaxNG; | ||||
1967 | |||||
1968 | sub CLONE_SKIP { 1 } | ||||
1969 | |||||
1970 | sub new { | ||||
1971 | my $class = shift; | ||||
1972 | my %args = @_; | ||||
1973 | |||||
1974 | my $self = undef; | ||||
1975 | if ( defined $args{location} ) { | ||||
1976 | $self = $class->parse_location( $args{location} ); | ||||
1977 | } | ||||
1978 | elsif ( defined $args{string} ) { | ||||
1979 | $self = $class->parse_buffer( $args{string} ); | ||||
1980 | } | ||||
1981 | elsif ( defined $args{DOM} ) { | ||||
1982 | $self = $class->parse_document( $args{DOM} ); | ||||
1983 | } | ||||
1984 | |||||
1985 | return $self; | ||||
1986 | } | ||||
1987 | |||||
1988 | 1; | ||||
1989 | |||||
1990 | package XML::LibXML::Schema; | ||||
1991 | |||||
1992 | sub CLONE_SKIP { 1 } | ||||
1993 | |||||
1994 | sub new { | ||||
1995 | my $class = shift; | ||||
1996 | my %args = @_; | ||||
1997 | |||||
1998 | my $self = undef; | ||||
1999 | if ( defined $args{location} ) { | ||||
2000 | $self = $class->parse_location( $args{location} ); | ||||
2001 | } | ||||
2002 | elsif ( defined $args{string} ) { | ||||
2003 | $self = $class->parse_buffer( $args{string} ); | ||||
2004 | } | ||||
2005 | |||||
2006 | return $self; | ||||
2007 | } | ||||
2008 | |||||
2009 | 1 | 300ns | 1; | ||
2010 | |||||
2011 | #-------------------------------------------------------------------------# | ||||
2012 | # XML::LibXML::Pattern Interface # | ||||
2013 | #-------------------------------------------------------------------------# | ||||
2014 | |||||
2015 | package XML::LibXML::Pattern; | ||||
2016 | |||||
2017 | sub CLONE_SKIP { 1 } | ||||
2018 | |||||
2019 | sub new { | ||||
2020 | my $class = shift; | ||||
2021 | my ($pattern,$ns_map)=@_; | ||||
2022 | my $self = undef; | ||||
2023 | |||||
2024 | unless (UNIVERSAL::can($class,'_compilePattern')) { | ||||
2025 | croak("Cannot create XML::LibXML::Pattern - ". | ||||
2026 | "your libxml2 is compiled without pattern support!"); | ||||
2027 | } | ||||
2028 | |||||
2029 | if (ref($ns_map) eq 'HASH') { | ||||
2030 | # translate prefix=>URL hash to a (URL,prefix) list | ||||
2031 | $self = $class->_compilePattern($pattern,0,[reverse %$ns_map]); | ||||
2032 | } else { | ||||
2033 | $self = $class->_compilePattern($pattern,0); | ||||
2034 | } | ||||
2035 | return $self; | ||||
2036 | } | ||||
2037 | |||||
2038 | 1; | ||||
2039 | |||||
2040 | #-------------------------------------------------------------------------# | ||||
2041 | # XML::LibXML::RegExp Interface # | ||||
2042 | #-------------------------------------------------------------------------# | ||||
2043 | |||||
2044 | package XML::LibXML::RegExp; | ||||
2045 | |||||
2046 | sub CLONE_SKIP { 1 } | ||||
2047 | |||||
2048 | sub new { | ||||
2049 | my $class = shift; | ||||
2050 | my ($regexp)=@_; | ||||
2051 | unless (UNIVERSAL::can($class,'_compile')) { | ||||
2052 | croak("Cannot create XML::LibXML::RegExp - ". | ||||
2053 | "your libxml2 is compiled without regexp support!"); | ||||
2054 | } | ||||
2055 | return $class->_compile($regexp); | ||||
2056 | } | ||||
2057 | |||||
2058 | 1 | 300ns | 1; | ||
2059 | |||||
2060 | #-------------------------------------------------------------------------# | ||||
2061 | # XML::LibXML::XPathExpression Interface # | ||||
2062 | #-------------------------------------------------------------------------# | ||||
2063 | |||||
2064 | package XML::LibXML::XPathExpression; | ||||
2065 | |||||
2066 | sub CLONE_SKIP { 1 } | ||||
2067 | |||||
2068 | 1; | ||||
2069 | |||||
2070 | |||||
2071 | #-------------------------------------------------------------------------# | ||||
2072 | # XML::LibXML::InputCallback Interface # | ||||
2073 | #-------------------------------------------------------------------------# | ||||
2074 | package XML::LibXML::InputCallback; | ||||
2075 | |||||
2076 | 2 | 327µs | 2 | 1.00ms | # spent 533µs (62+472) within XML::LibXML::InputCallback::BEGIN@2076 which was called:
# once (62µs+472µs) by XML::LibXML::SAX::BEGIN@17 at line 2076 # spent 533µs making 1 call to XML::LibXML::InputCallback::BEGIN@2076
# spent 472µs making 1 call to vars::import |
2077 | |||||
2078 | # spent 32µs within XML::LibXML::InputCallback::BEGIN@2078 which was called:
# once (32µs+0s) by XML::LibXML::SAX::BEGIN@17 at line 2084 | ||||
2079 | 1 | 1µs | $_CUR_CB = undef; | ||
2080 | 1 | 4µs | @_GLOBAL_CALLBACKS = (); | ||
2081 | 1 | 900ns | @_CB_STACK = (); | ||
2082 | 1 | 1µs | $_CB_NESTED_DEPTH = 0; | ||
2083 | 1 | 26µs | @_CB_NESTED_STACK = (); | ||
2084 | 1 | 3.89ms | 1 | 32µs | } # spent 32µs making 1 call to XML::LibXML::InputCallback::BEGIN@2078 |
2085 | |||||
2086 | sub CLONE_SKIP { | ||||
2087 | return $XML::LibXML::__threads_shared ? 0 : 1; | ||||
2088 | } | ||||
2089 | |||||
2090 | #-------------------------------------------------------------------------# | ||||
2091 | # global callbacks # | ||||
2092 | #-------------------------------------------------------------------------# | ||||
2093 | sub _callback_match { | ||||
2094 | my $uri = shift; | ||||
2095 | my $retval = 0; | ||||
2096 | |||||
2097 | # loop through the callbacks and and find the first matching | ||||
2098 | # The callbacks are stored in execution order (reverse stack order) | ||||
2099 | # any new global callbacks are shifted to the callback stack. | ||||
2100 | foreach my $cb ( @_GLOBAL_CALLBACKS ) { | ||||
2101 | |||||
2102 | # callbacks have to return 1, 0 or undef, while 0 and undef | ||||
2103 | # are handled the same way. | ||||
2104 | # in fact, if callbacks return other values, the global match | ||||
2105 | # assumes silently that the callback failed. | ||||
2106 | |||||
2107 | $retval = $cb->[0]->($uri); | ||||
2108 | |||||
2109 | if ( defined $retval and $retval == 1 ) { | ||||
2110 | # make the other callbacks use this callback | ||||
2111 | $_CUR_CB = $cb; | ||||
2112 | unshift @_CB_STACK, $cb; | ||||
2113 | last; | ||||
2114 | } | ||||
2115 | } | ||||
2116 | |||||
2117 | return $retval; | ||||
2118 | } | ||||
2119 | |||||
2120 | sub _callback_open { | ||||
2121 | my $uri = shift; | ||||
2122 | my $retval = undef; | ||||
2123 | |||||
2124 | # the open callback has to return a defined value. | ||||
2125 | # if one works on files this can be a file handle. But | ||||
2126 | # depending on the needs of the callback it also can be a | ||||
2127 | # database handle or a integer labeling a certain dataset. | ||||
2128 | |||||
2129 | if ( defined $_CUR_CB ) { | ||||
2130 | $retval = $_CUR_CB->[1]->( $uri ); | ||||
2131 | |||||
2132 | # reset the callbacks, if one callback cannot open an uri | ||||
2133 | if ( not defined $retval or $retval == 0 ) { | ||||
2134 | shift @_CB_STACK; | ||||
2135 | $_CUR_CB = $_CB_STACK[0]; | ||||
2136 | } | ||||
2137 | } | ||||
2138 | |||||
2139 | return $retval; | ||||
2140 | } | ||||
2141 | |||||
2142 | sub _callback_read { | ||||
2143 | my $fh = shift; | ||||
2144 | my $buflen = shift; | ||||
2145 | |||||
2146 | my $retval = undef; | ||||
2147 | |||||
2148 | if ( defined $_CUR_CB ) { | ||||
2149 | $retval = $_CUR_CB->[2]->( $fh, $buflen ); | ||||
2150 | } | ||||
2151 | |||||
2152 | return $retval; | ||||
2153 | } | ||||
2154 | |||||
2155 | sub _callback_close { | ||||
2156 | my $fh = shift; | ||||
2157 | my $retval = 0; | ||||
2158 | |||||
2159 | if ( defined $_CUR_CB ) { | ||||
2160 | $retval = $_CUR_CB->[3]->( $fh ); | ||||
2161 | shift @_CB_STACK; | ||||
2162 | $_CUR_CB = $_CB_STACK[0]; | ||||
2163 | } | ||||
2164 | |||||
2165 | return $retval; | ||||
2166 | } | ||||
2167 | |||||
2168 | #-------------------------------------------------------------------------# | ||||
2169 | # member functions and methods # | ||||
2170 | #-------------------------------------------------------------------------# | ||||
2171 | |||||
2172 | # spent 80µs within XML::LibXML::InputCallback::new which was called 2 times, avg 40µs/call:
# 2 times (80µs+0s) by XML::LibXML::_init_callbacks at line 729, avg 40µs/call | ||||
2173 | 2 | 7µs | my $CLASS = shift; | ||
2174 | 2 | 99µs | return bless {'_CALLBACKS' => []}, $CLASS; | ||
2175 | } | ||||
2176 | |||||
2177 | # add a callback set to the callback stack | ||||
2178 | # synopsis: $icb->register_callbacks( [$match_cb, $open_cb, $read_cb, $close_cb] ); | ||||
2179 | sub register_callbacks { | ||||
2180 | my $self = shift; | ||||
2181 | my $cbset = shift; | ||||
2182 | |||||
2183 | # test if callback set is complete | ||||
2184 | if ( ref $cbset eq "ARRAY" and scalar( @$cbset ) == 4 ) { | ||||
2185 | unshift @{$self->{_CALLBACKS}}, $cbset; | ||||
2186 | } | ||||
2187 | } | ||||
2188 | |||||
2189 | # remove a callback set to the callback stack | ||||
2190 | # if a callback set is passed, this function will check for the match function | ||||
2191 | sub unregister_callbacks { | ||||
2192 | my $self = shift; | ||||
2193 | my $cbset = shift; | ||||
2194 | if ( ref $cbset eq "ARRAY" and scalar( @$cbset ) == 4 ) { | ||||
2195 | $self->{_CALLBACKS} = [grep { $_->[0] != $cbset->[0] } @{$self->{_CALLBACKS}}]; | ||||
2196 | } | ||||
2197 | else { | ||||
2198 | shift @{$self->{_CALLBACKS}}; | ||||
2199 | } | ||||
2200 | } | ||||
2201 | |||||
2202 | # make libxml2 use the callbacks | ||||
2203 | # spent 492µs (319+174) within XML::LibXML::InputCallback::init_callbacks which was called 2 times, avg 246µs/call:
# 2 times (319µs+174µs) by XML::LibXML::_init_callbacks at line 733, avg 246µs/call | ||||
2204 | 2 | 4µs | my $self = shift; | ||
2205 | 2 | 2µs | my $parser = shift; | ||
2206 | |||||
2207 | #initialize the libxml2 callbacks unless this is a nested callback | ||||
2208 | 2 | 87µs | 2 | 33µs | $self->lib_init_callbacks() unless($_CB_NESTED_DEPTH); # spent 33µs making 2 calls to XML::LibXML::InputCallback::lib_init_callbacks, avg 17µs/call |
2209 | |||||
2210 | #store the callbacks for any outer executing parser instance | ||||
2211 | 2 | 2µs | $_CB_NESTED_DEPTH++; | ||
2212 | 2 | 21µs | push @_CB_NESTED_STACK, [ | ||
2213 | $_CUR_CB, | ||||
2214 | [@_CB_STACK], | ||||
2215 | [@_GLOBAL_CALLBACKS], | ||||
2216 | ]; | ||||
2217 | |||||
2218 | #initialize the callback variables for the current parser | ||||
2219 | 2 | 2µs | $_CUR_CB = undef; | ||
2220 | 2 | 7µs | @_CB_STACK = (); | ||
2221 | 2 | 7µs | @_GLOBAL_CALLBACKS = @{ $self->{_CALLBACKS} }; | ||
2222 | |||||
2223 | #attach parser specific callbacks | ||||
2224 | 2 | 5µs | if($parser) { | ||
2225 | 2 | 26µs | 2 | 38µs | my $mcb = $parser->match_callback(); # spent 38µs making 2 calls to XML::LibXML::match_callback, avg 19µs/call |
2226 | 2 | 25µs | 2 | 34µs | my $ocb = $parser->open_callback(); # spent 34µs making 2 calls to XML::LibXML::open_callback, avg 17µs/call |
2227 | 2 | 23µs | 2 | 35µs | my $rcb = $parser->read_callback(); # spent 35µs making 2 calls to XML::LibXML::read_callback, avg 17µs/call |
2228 | 2 | 20µs | 2 | 33µs | my $ccb = $parser->close_callback(); # spent 33µs making 2 calls to XML::LibXML::close_callback, avg 17µs/call |
2229 | 2 | 6µs | if ( defined $mcb and defined $ocb and defined $rcb and defined $ccb ) { | ||
2230 | unshift @_GLOBAL_CALLBACKS, [$mcb, $ocb, $rcb, $ccb]; | ||||
2231 | } | ||||
2232 | } | ||||
2233 | |||||
2234 | #attach global callbacks | ||||
2235 | 2 | 38µs | if ( defined $XML::LibXML::match_cb and | ||
2236 | defined $XML::LibXML::open_cb and | ||||
2237 | defined $XML::LibXML::read_cb and | ||||
2238 | defined $XML::LibXML::close_cb ) { | ||||
2239 | push @_GLOBAL_CALLBACKS, [$XML::LibXML::match_cb, | ||||
2240 | $XML::LibXML::open_cb, | ||||
2241 | $XML::LibXML::read_cb, | ||||
2242 | $XML::LibXML::close_cb]; | ||||
2243 | } | ||||
2244 | } | ||||
2245 | |||||
2246 | # reset libxml2's callbacks | ||||
2247 | # spent 132µs (104+28) within XML::LibXML::InputCallback::cleanup_callbacks which was called 2 times, avg 66µs/call:
# 2 times (104µs+28µs) by XML::LibXML::_cleanup_callbacks at line 738, avg 66µs/call | ||||
2248 | 2 | 4µs | my $self = shift; | ||
2249 | |||||
2250 | #restore the callbacks for the outer parser instance | ||||
2251 | 2 | 2µs | $_CB_NESTED_DEPTH--; | ||
2252 | 2 | 6µs | my $saved = pop @_CB_NESTED_STACK; | ||
2253 | 2 | 4µs | $_CUR_CB = $saved->[0]; | ||
2254 | 2 | 10µs | @_CB_STACK = (@{$saved->[1]}); | ||
2255 | 2 | 6µs | @_GLOBAL_CALLBACKS = (@{$saved->[2]}); | ||
2256 | |||||
2257 | #clean up the libxml2 callbacks unless there are still outer parsing instances | ||||
2258 | 2 | 113µs | 2 | 28µs | $self->lib_cleanup_callbacks() unless($_CB_NESTED_DEPTH); # spent 28µs making 2 calls to XML::LibXML::InputCallback::lib_cleanup_callbacks, avg 14µs/call |
2259 | } | ||||
2260 | |||||
2261 | 1 | 2µs | $XML::LibXML::__loaded=1; | ||
2262 | |||||
2263 | 1 | 107µs | 1; | ||
2264 | |||||
2265 | __END__ | ||||
sub XML::LibXML::CORE:match; # opcode | |||||
# spent 51µs within XML::LibXML::END which was called:
# once (51µs+0s) by main::RUNTIME at line 0 of webmerge/scripts/webmerge.pl | |||||
# spent 28µs within XML::LibXML::InputCallback::lib_cleanup_callbacks which was called 2 times, avg 14µs/call:
# 2 times (28µs+0s) by XML::LibXML::InputCallback::cleanup_callbacks at line 2258, avg 14µs/call | |||||
# spent 33µs within XML::LibXML::InputCallback::lib_init_callbacks which was called 2 times, avg 17µs/call:
# 2 times (33µs+0s) by XML::LibXML::InputCallback::init_callbacks at line 2208, avg 17µs/call | |||||
# spent 31µs within XML::LibXML::LIBXML_RUNTIME_VERSION which was called:
# once (31µs+0s) by XML::LibXML::SAX::BEGIN@17 at line 222 | |||||
# spent 15µs within XML::LibXML::LIBXML_VERSION which was called:
# once (15µs+0s) by XML::LibXML::SAX::BEGIN@17 at line 223 | |||||
# spent 132ms (56.9+74.9) within XML::LibXML::_parse_sax_string which was called 2 times, avg 65.9ms/call:
# 2 times (56.9ms+74.9ms) by XML::LibXML::parse_string at line 833, avg 65.9ms/call | |||||
# spent 4.06ms within XML::LibXML::bootstrap which was called:
# once (4.06ms+0s) by DynaLoader::bootstrap at line 213 of DynaLoader.pm |