nokogiri 1.5.10 → 1.12.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of nokogiri might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/LICENSE-DEPENDENCIES.md +1903 -0
- data/LICENSE.md +9 -0
- data/README.md +278 -0
- data/bin/nokogiri +50 -10
- data/dependencies.yml +74 -0
- data/ext/nokogiri/depend +38 -358
- data/ext/nokogiri/extconf.rb +944 -100
- data/ext/nokogiri/gumbo.c +584 -0
- data/ext/nokogiri/html4_document.c +166 -0
- data/ext/nokogiri/html4_element_description.c +294 -0
- data/ext/nokogiri/html4_entity_lookup.c +37 -0
- data/ext/nokogiri/html4_sax_parser_context.c +120 -0
- data/ext/nokogiri/html4_sax_push_parser.c +95 -0
- data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
- data/ext/nokogiri/nokogiri.c +232 -87
- data/ext/nokogiri/nokogiri.h +188 -129
- data/ext/nokogiri/test_global_handlers.c +40 -0
- data/ext/nokogiri/xml_attr.c +49 -40
- data/ext/nokogiri/xml_attribute_decl.c +18 -18
- data/ext/nokogiri/xml_cdata.c +24 -23
- data/ext/nokogiri/xml_comment.c +29 -21
- data/ext/nokogiri/xml_document.c +305 -201
- data/ext/nokogiri/xml_document_fragment.c +13 -15
- data/ext/nokogiri/xml_dtd.c +54 -48
- data/ext/nokogiri/xml_element_content.c +31 -26
- data/ext/nokogiri/xml_element_decl.c +22 -22
- data/ext/nokogiri/xml_encoding_handler.c +30 -19
- data/ext/nokogiri/xml_entity_decl.c +32 -30
- data/ext/nokogiri/xml_entity_reference.c +16 -18
- data/ext/nokogiri/xml_namespace.c +74 -32
- data/ext/nokogiri/xml_node.c +808 -503
- data/ext/nokogiri/xml_node_set.c +239 -208
- data/ext/nokogiri/xml_processing_instruction.c +17 -19
- data/ext/nokogiri/xml_reader.c +198 -186
- data/ext/nokogiri/xml_relax_ng.c +52 -28
- data/ext/nokogiri/xml_sax_parser.c +123 -125
- data/ext/nokogiri/xml_sax_parser_context.c +138 -79
- data/ext/nokogiri/xml_sax_push_parser.c +88 -35
- data/ext/nokogiri/xml_schema.c +112 -33
- data/ext/nokogiri/xml_syntax_error.c +50 -23
- data/ext/nokogiri/xml_text.c +14 -18
- data/ext/nokogiri/xml_xpath_context.c +162 -98
- data/ext/nokogiri/xslt_stylesheet.c +162 -168
- data/gumbo-parser/CHANGES.md +63 -0
- data/gumbo-parser/Makefile +101 -0
- data/gumbo-parser/THANKS +27 -0
- data/gumbo-parser/src/Makefile +34 -0
- data/gumbo-parser/src/README.md +41 -0
- data/gumbo-parser/src/ascii.c +75 -0
- data/gumbo-parser/src/ascii.h +115 -0
- data/gumbo-parser/src/attribute.c +42 -0
- data/gumbo-parser/src/attribute.h +17 -0
- data/gumbo-parser/src/char_ref.c +22225 -0
- data/gumbo-parser/src/char_ref.h +29 -0
- data/gumbo-parser/src/char_ref.rl +2154 -0
- data/gumbo-parser/src/error.c +626 -0
- data/gumbo-parser/src/error.h +148 -0
- data/gumbo-parser/src/foreign_attrs.c +104 -0
- data/gumbo-parser/src/foreign_attrs.gperf +27 -0
- data/gumbo-parser/src/gumbo.h +943 -0
- data/gumbo-parser/src/insertion_mode.h +33 -0
- data/gumbo-parser/src/macros.h +91 -0
- data/gumbo-parser/src/parser.c +4886 -0
- data/gumbo-parser/src/parser.h +41 -0
- data/gumbo-parser/src/replacement.h +33 -0
- data/gumbo-parser/src/string_buffer.c +103 -0
- data/gumbo-parser/src/string_buffer.h +68 -0
- data/gumbo-parser/src/string_piece.c +48 -0
- data/gumbo-parser/src/svg_attrs.c +174 -0
- data/gumbo-parser/src/svg_attrs.gperf +77 -0
- data/gumbo-parser/src/svg_tags.c +137 -0
- data/gumbo-parser/src/svg_tags.gperf +55 -0
- data/gumbo-parser/src/tag.c +222 -0
- data/gumbo-parser/src/tag_lookup.c +382 -0
- data/gumbo-parser/src/tag_lookup.gperf +169 -0
- data/gumbo-parser/src/tag_lookup.h +13 -0
- data/gumbo-parser/src/token_buffer.c +79 -0
- data/gumbo-parser/src/token_buffer.h +71 -0
- data/gumbo-parser/src/token_type.h +17 -0
- data/gumbo-parser/src/tokenizer.c +3463 -0
- data/gumbo-parser/src/tokenizer.h +112 -0
- data/gumbo-parser/src/tokenizer_states.h +339 -0
- data/gumbo-parser/src/utf8.c +245 -0
- data/gumbo-parser/src/utf8.h +164 -0
- data/gumbo-parser/src/util.c +68 -0
- data/gumbo-parser/src/util.h +30 -0
- data/gumbo-parser/src/vector.c +111 -0
- data/gumbo-parser/src/vector.h +45 -0
- data/lib/nokogiri/css/node.rb +1 -50
- data/lib/nokogiri/css/parser.rb +317 -286
- data/lib/nokogiri/css/parser.y +57 -43
- data/lib/nokogiri/css/parser_extras.rb +39 -36
- data/lib/nokogiri/css/syntax_error.rb +2 -1
- data/lib/nokogiri/css/tokenizer.rb +105 -103
- data/lib/nokogiri/css/tokenizer.rex +5 -5
- data/lib/nokogiri/css/xpath_visitor.rb +137 -48
- data/lib/nokogiri/css.rb +15 -14
- data/lib/nokogiri/decorators/slop.rb +13 -5
- data/lib/nokogiri/extension.rb +31 -0
- data/lib/nokogiri/gumbo.rb +14 -0
- data/lib/nokogiri/html.rb +32 -27
- data/lib/nokogiri/{html → html4}/builder.rb +3 -2
- data/lib/nokogiri/{html → html4}/document.rb +118 -50
- data/lib/nokogiri/{html → html4}/document_fragment.rb +20 -11
- data/lib/nokogiri/{html → html4}/element_description.rb +2 -1
- data/lib/nokogiri/{html → html4}/element_description_defaults.rb +2 -1
- data/lib/nokogiri/{html → html4}/entity_lookup.rb +2 -1
- data/lib/nokogiri/{html → html4}/sax/parser.rb +22 -14
- data/lib/nokogiri/html4/sax/parser_context.rb +19 -0
- data/lib/nokogiri/html4/sax/push_parser.rb +37 -0
- data/lib/nokogiri/html4.rb +40 -0
- data/lib/nokogiri/html5/document.rb +74 -0
- data/lib/nokogiri/html5/document_fragment.rb +80 -0
- data/lib/nokogiri/html5/node.rb +93 -0
- data/lib/nokogiri/html5.rb +473 -0
- data/lib/nokogiri/jruby/dependencies.rb +20 -0
- data/lib/nokogiri/syntax_error.rb +1 -0
- data/lib/nokogiri/version/constant.rb +5 -0
- data/lib/nokogiri/version/info.rb +215 -0
- data/lib/nokogiri/version.rb +3 -91
- data/lib/nokogiri/xml/attr.rb +1 -0
- data/lib/nokogiri/xml/attribute_decl.rb +1 -0
- data/lib/nokogiri/xml/builder.rb +75 -33
- data/lib/nokogiri/xml/cdata.rb +1 -0
- data/lib/nokogiri/xml/character_data.rb +1 -0
- data/lib/nokogiri/xml/document.rb +157 -54
- data/lib/nokogiri/xml/document_fragment.rb +55 -8
- data/lib/nokogiri/xml/dtd.rb +15 -4
- data/lib/nokogiri/xml/element_content.rb +1 -0
- data/lib/nokogiri/xml/element_decl.rb +1 -0
- data/lib/nokogiri/xml/entity_decl.rb +1 -0
- data/lib/nokogiri/xml/entity_reference.rb +19 -0
- data/lib/nokogiri/xml/namespace.rb +1 -0
- data/lib/nokogiri/xml/node/save_options.rb +2 -1
- data/lib/nokogiri/xml/node.rb +712 -431
- data/lib/nokogiri/xml/node_set.rb +140 -123
- data/lib/nokogiri/xml/notation.rb +1 -0
- data/lib/nokogiri/xml/parse_options.rb +31 -0
- data/lib/nokogiri/xml/pp/character_data.rb +1 -0
- data/lib/nokogiri/xml/pp/node.rb +1 -0
- data/lib/nokogiri/xml/pp.rb +3 -2
- data/lib/nokogiri/xml/processing_instruction.rb +1 -0
- data/lib/nokogiri/xml/reader.rb +9 -12
- data/lib/nokogiri/xml/relax_ng.rb +7 -2
- data/lib/nokogiri/xml/sax/document.rb +25 -30
- data/lib/nokogiri/xml/sax/parser.rb +8 -8
- data/lib/nokogiri/xml/sax/parser_context.rb +1 -0
- data/lib/nokogiri/xml/sax/push_parser.rb +1 -0
- data/lib/nokogiri/xml/sax.rb +5 -4
- data/lib/nokogiri/xml/schema.rb +13 -4
- data/lib/nokogiri/xml/searchable.rb +239 -0
- data/lib/nokogiri/xml/syntax_error.rb +25 -1
- data/lib/nokogiri/xml/text.rb +1 -0
- data/lib/nokogiri/xml/xpath/syntax_error.rb +2 -1
- data/lib/nokogiri/xml/xpath.rb +4 -5
- data/lib/nokogiri/xml/xpath_context.rb +1 -0
- data/lib/nokogiri/xml.rb +37 -35
- data/lib/nokogiri/xslt/stylesheet.rb +2 -1
- data/lib/nokogiri/xslt.rb +17 -16
- data/lib/nokogiri.rb +55 -58
- data/lib/xsd/xmlparser/nokogiri.rb +1 -0
- data/patches/libxml2/0001-Remove-script-macro-support.patch +40 -0
- data/patches/libxml2/0002-Update-entities-to-remove-handling-of-ssi.patch +44 -0
- data/patches/libxml2/0003-libxml2.la-is-in-top_builddir.patch +25 -0
- data/patches/libxml2/0004-use-glibc-strlen.patch +53 -0
- data/patches/libxml2/0005-avoid-isnan-isinf.patch +81 -0
- data/patches/libxml2/0006-update-automake-files-for-arm64.patch +2511 -0
- data/patches/libxml2/0007-Fix-XPath-recursion-limit.patch +31 -0
- data/patches/libxslt/0001-update-automake-files-for-arm64.patch +2511 -0
- data/patches/libxslt/0002-Fix-xml2-config-check-in-configure-script.patch +19 -0
- data/ports/archives/libxml2-2.9.12.tar.gz +0 -0
- data/ports/archives/libxslt-1.1.34.tar.gz +0 -0
- metadata +307 -459
- data/.autotest +0 -26
- data/.gemtest +0 -0
- data/CHANGELOG.ja.rdoc +0 -785
- data/CHANGELOG.rdoc +0 -783
- data/C_CODING_STYLE.rdoc +0 -33
- data/Manifest.txt +0 -303
- data/README.ja.rdoc +0 -106
- data/README.rdoc +0 -175
- data/ROADMAP.md +0 -90
- data/Rakefile +0 -228
- data/STANDARD_RESPONSES.md +0 -47
- data/Y_U_NO_GEMSPEC.md +0 -155
- data/build_all +0 -105
- data/ext/nokogiri/html_document.c +0 -170
- data/ext/nokogiri/html_document.h +0 -10
- data/ext/nokogiri/html_element_description.c +0 -279
- data/ext/nokogiri/html_element_description.h +0 -10
- data/ext/nokogiri/html_entity_lookup.c +0 -32
- data/ext/nokogiri/html_entity_lookup.h +0 -8
- data/ext/nokogiri/html_sax_parser_context.c +0 -116
- data/ext/nokogiri/html_sax_parser_context.h +0 -11
- data/ext/nokogiri/html_sax_push_parser.c +0 -87
- data/ext/nokogiri/html_sax_push_parser.h +0 -9
- data/ext/nokogiri/xml_attr.h +0 -9
- data/ext/nokogiri/xml_attribute_decl.h +0 -9
- data/ext/nokogiri/xml_cdata.h +0 -9
- data/ext/nokogiri/xml_comment.h +0 -9
- data/ext/nokogiri/xml_document.h +0 -23
- data/ext/nokogiri/xml_document_fragment.h +0 -10
- data/ext/nokogiri/xml_dtd.h +0 -10
- data/ext/nokogiri/xml_element_content.h +0 -10
- data/ext/nokogiri/xml_element_decl.h +0 -9
- data/ext/nokogiri/xml_encoding_handler.h +0 -8
- data/ext/nokogiri/xml_entity_decl.h +0 -10
- data/ext/nokogiri/xml_entity_reference.h +0 -9
- data/ext/nokogiri/xml_io.c +0 -56
- data/ext/nokogiri/xml_io.h +0 -11
- data/ext/nokogiri/xml_libxml2_hacks.c +0 -112
- data/ext/nokogiri/xml_libxml2_hacks.h +0 -12
- data/ext/nokogiri/xml_namespace.h +0 -13
- data/ext/nokogiri/xml_node.h +0 -13
- data/ext/nokogiri/xml_node_set.h +0 -14
- data/ext/nokogiri/xml_processing_instruction.h +0 -9
- data/ext/nokogiri/xml_reader.h +0 -10
- data/ext/nokogiri/xml_relax_ng.h +0 -9
- data/ext/nokogiri/xml_sax_parser.h +0 -39
- data/ext/nokogiri/xml_sax_parser_context.h +0 -10
- data/ext/nokogiri/xml_sax_push_parser.h +0 -9
- data/ext/nokogiri/xml_schema.h +0 -9
- data/ext/nokogiri/xml_syntax_error.h +0 -13
- data/ext/nokogiri/xml_text.h +0 -9
- data/ext/nokogiri/xml_xpath_context.h +0 -10
- data/ext/nokogiri/xslt_stylesheet.h +0 -14
- data/lib/nokogiri/html/sax/parser_context.rb +0 -16
- data/lib/nokogiri/html/sax/push_parser.rb +0 -16
- data/tasks/cross_compile.rb +0 -150
- data/tasks/nokogiri.org.rb +0 -24
- data/tasks/test.rb +0 -95
- data/test/css/test_nthiness.rb +0 -159
- data/test/css/test_parser.rb +0 -341
- data/test/css/test_tokenizer.rb +0 -198
- data/test/css/test_xpath_visitor.rb +0 -91
- data/test/decorators/test_slop.rb +0 -16
- data/test/files/2ch.html +0 -108
- data/test/files/address_book.rlx +0 -12
- data/test/files/address_book.xml +0 -10
- data/test/files/bar/bar.xsd +0 -4
- data/test/files/dont_hurt_em_why.xml +0 -422
- data/test/files/encoding.html +0 -82
- data/test/files/encoding.xhtml +0 -84
- data/test/files/exslt.xml +0 -8
- data/test/files/exslt.xslt +0 -35
- data/test/files/foo/foo.xsd +0 -4
- data/test/files/metacharset.html +0 -10
- data/test/files/noencoding.html +0 -47
- data/test/files/po.xml +0 -32
- data/test/files/po.xsd +0 -66
- data/test/files/shift_jis.html +0 -10
- data/test/files/shift_jis.xml +0 -5
- data/test/files/snuggles.xml +0 -3
- data/test/files/staff.dtd +0 -10
- data/test/files/staff.xml +0 -59
- data/test/files/staff.xslt +0 -32
- data/test/files/test_document_url/bar.xml +0 -2
- data/test/files/test_document_url/document.dtd +0 -4
- data/test/files/test_document_url/document.xml +0 -6
- data/test/files/tlm.html +0 -850
- data/test/files/to_be_xincluded.xml +0 -2
- data/test/files/valid_bar.xml +0 -2
- data/test/files/xinclude.xml +0 -4
- data/test/helper.rb +0 -154
- data/test/html/sax/test_parser.rb +0 -141
- data/test/html/sax/test_parser_context.rb +0 -46
- data/test/html/test_builder.rb +0 -164
- data/test/html/test_document.rb +0 -552
- data/test/html/test_document_encoding.rb +0 -138
- data/test/html/test_document_fragment.rb +0 -261
- data/test/html/test_element_description.rb +0 -105
- data/test/html/test_named_characters.rb +0 -14
- data/test/html/test_node.rb +0 -196
- data/test/html/test_node_encoding.rb +0 -27
- data/test/namespaces/test_additional_namespaces_in_builder_doc.rb +0 -14
- data/test/namespaces/test_namespaces_in_builder_doc.rb +0 -75
- data/test/namespaces/test_namespaces_in_created_doc.rb +0 -75
- data/test/namespaces/test_namespaces_in_parsed_doc.rb +0 -66
- data/test/test_convert_xpath.rb +0 -135
- data/test/test_css_cache.rb +0 -45
- data/test/test_encoding_handler.rb +0 -46
- data/test/test_memory_leak.rb +0 -156
- data/test/test_nokogiri.rb +0 -132
- data/test/test_reader.rb +0 -555
- data/test/test_soap4r_sax.rb +0 -52
- data/test/test_xslt_transforms.rb +0 -254
- data/test/xml/node/test_save_options.rb +0 -28
- data/test/xml/node/test_subclass.rb +0 -44
- data/test/xml/sax/test_parser.rb +0 -366
- data/test/xml/sax/test_parser_context.rb +0 -106
- data/test/xml/sax/test_push_parser.rb +0 -157
- data/test/xml/test_attr.rb +0 -64
- data/test/xml/test_attribute_decl.rb +0 -86
- data/test/xml/test_builder.rb +0 -306
- data/test/xml/test_c14n.rb +0 -151
- data/test/xml/test_cdata.rb +0 -48
- data/test/xml/test_comment.rb +0 -29
- data/test/xml/test_document.rb +0 -828
- data/test/xml/test_document_encoding.rb +0 -28
- data/test/xml/test_document_fragment.rb +0 -223
- data/test/xml/test_dtd.rb +0 -103
- data/test/xml/test_dtd_encoding.rb +0 -33
- data/test/xml/test_element_content.rb +0 -56
- data/test/xml/test_element_decl.rb +0 -73
- data/test/xml/test_entity_decl.rb +0 -122
- data/test/xml/test_entity_reference.rb +0 -245
- data/test/xml/test_namespace.rb +0 -95
- data/test/xml/test_node.rb +0 -1137
- data/test/xml/test_node_attributes.rb +0 -96
- data/test/xml/test_node_encoding.rb +0 -107
- data/test/xml/test_node_inheritance.rb +0 -32
- data/test/xml/test_node_reparenting.rb +0 -374
- data/test/xml/test_node_set.rb +0 -755
- data/test/xml/test_parse_options.rb +0 -64
- data/test/xml/test_processing_instruction.rb +0 -30
- data/test/xml/test_reader_encoding.rb +0 -142
- data/test/xml/test_relax_ng.rb +0 -60
- data/test/xml/test_schema.rb +0 -103
- data/test/xml/test_syntax_error.rb +0 -12
- data/test/xml/test_text.rb +0 -45
- data/test/xml/test_unparented_node.rb +0 -422
- data/test/xml/test_xinclude.rb +0 -83
- data/test/xml/test_xpath.rb +0 -295
- data/test/xslt/test_custom_functions.rb +0 -133
- data/test/xslt/test_exception_handling.rb +0 -37
- data/test_all +0 -81
data/ext/nokogiri/xml_node.c
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
-
#include <
|
1
|
+
#include <nokogiri.h>
|
2
2
|
|
3
|
-
|
3
|
+
VALUE cNokogiriXmlNode ;
|
4
|
+
|
5
|
+
static ID id_decorate, id_decorate_bang;
|
4
6
|
|
5
7
|
#ifdef DEBUG
|
6
|
-
static void
|
8
|
+
static void
|
9
|
+
debug_node_dealloc(xmlNodePtr x)
|
7
10
|
{
|
8
11
|
NOKOGIRI_DEBUG_START(x)
|
9
12
|
NOKOGIRI_DEBUG_END(x)
|
@@ -12,70 +15,87 @@ static void debug_node_dealloc(xmlNodePtr x)
|
|
12
15
|
# define debug_node_dealloc 0
|
13
16
|
#endif
|
14
17
|
|
15
|
-
static void
|
18
|
+
static void
|
19
|
+
mark(xmlNodePtr node)
|
16
20
|
{
|
17
|
-
|
21
|
+
xmlDocPtr doc = node->doc;
|
22
|
+
if (doc->type == XML_DOCUMENT_NODE || doc->type == XML_HTML_DOCUMENT_NODE) {
|
23
|
+
if (DOC_RUBY_OBJECT_TEST(doc)) {
|
24
|
+
rb_gc_mark(DOC_RUBY_OBJECT(doc));
|
25
|
+
}
|
26
|
+
} else if (node->doc->_private) {
|
27
|
+
rb_gc_mark((VALUE)doc->_private);
|
28
|
+
}
|
18
29
|
}
|
19
30
|
|
20
31
|
/* :nodoc: */
|
21
|
-
typedef xmlNodePtr
|
32
|
+
typedef xmlNodePtr(*pivot_reparentee_func)(xmlNodePtr, xmlNodePtr);
|
22
33
|
|
23
34
|
/* :nodoc: */
|
24
|
-
static void
|
35
|
+
static void
|
36
|
+
relink_namespace(xmlNodePtr reparented)
|
25
37
|
{
|
26
|
-
xmlChar *name, *prefix;
|
27
38
|
xmlNodePtr child;
|
28
|
-
|
39
|
+
xmlAttrPtr attr;
|
29
40
|
|
30
41
|
if (reparented->type != XML_ATTRIBUTE_NODE &&
|
31
|
-
reparented->type != XML_ELEMENT_NODE) return;
|
42
|
+
reparented->type != XML_ELEMENT_NODE) { return; }
|
32
43
|
|
33
44
|
if (reparented->ns == NULL || reparented->ns->prefix == NULL) {
|
45
|
+
xmlNsPtr ns = NULL;
|
46
|
+
xmlChar *name = NULL, *prefix = NULL;
|
47
|
+
|
34
48
|
name = xmlSplitQName2(reparented->name, &prefix);
|
35
49
|
|
36
|
-
if(reparented->type == XML_ATTRIBUTE_NODE) {
|
37
|
-
if (prefix == NULL || strcmp((char*)prefix, XMLNS_PREFIX) == 0)
|
50
|
+
if (reparented->type == XML_ATTRIBUTE_NODE) {
|
51
|
+
if (prefix == NULL || strcmp((char *)prefix, XMLNS_PREFIX) == 0) {
|
52
|
+
xmlFree(name);
|
53
|
+
xmlFree(prefix);
|
54
|
+
return;
|
55
|
+
}
|
38
56
|
}
|
39
57
|
|
40
58
|
ns = xmlSearchNs(reparented->doc, reparented, prefix);
|
41
59
|
|
42
|
-
if (ns == NULL && reparented->parent) {
|
43
|
-
ns = xmlSearchNs(reparented->doc, reparented->parent, prefix);
|
44
|
-
}
|
45
|
-
|
46
60
|
if (ns != NULL) {
|
47
61
|
xmlNodeSetName(reparented, name);
|
48
62
|
xmlSetNs(reparented, ns);
|
49
63
|
}
|
64
|
+
|
65
|
+
xmlFree(name);
|
66
|
+
xmlFree(prefix);
|
50
67
|
}
|
51
68
|
|
52
69
|
/* Avoid segv when relinking against unlinked nodes. */
|
53
|
-
if (reparented->type != XML_ELEMENT_NODE || !reparented->parent) return;
|
70
|
+
if (reparented->type != XML_ELEMENT_NODE || !reparented->parent) { return; }
|
54
71
|
|
55
72
|
/* Make sure that our reparented node has the correct namespaces */
|
56
|
-
if(!reparented->ns &&
|
73
|
+
if (!reparented->ns &&
|
74
|
+
(reparented->doc != (xmlDocPtr)reparented->parent) &&
|
75
|
+
(rb_iv_get(DOC_RUBY_OBJECT(reparented->doc), "@namespace_inheritance") == Qtrue)) {
|
57
76
|
xmlSetNs(reparented, reparented->parent->ns);
|
77
|
+
}
|
58
78
|
|
59
79
|
/* Search our parents for an existing definition */
|
60
|
-
if(reparented->nsDef) {
|
80
|
+
if (reparented->nsDef) {
|
61
81
|
xmlNsPtr curr = reparented->nsDef;
|
62
82
|
xmlNsPtr prev = NULL;
|
63
83
|
|
64
|
-
while(curr) {
|
84
|
+
while (curr) {
|
65
85
|
xmlNsPtr ns = xmlSearchNsByHref(
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
86
|
+
reparented->doc,
|
87
|
+
reparented->parent,
|
88
|
+
curr->href
|
89
|
+
);
|
70
90
|
/* If we find the namespace is already declared, remove it from this
|
71
91
|
* definition list. */
|
72
|
-
if(ns && ns != curr) {
|
92
|
+
if (ns && ns != curr && xmlStrEqual(ns->prefix, curr->prefix)) {
|
73
93
|
if (prev) {
|
74
94
|
prev->next = curr->next;
|
75
95
|
} else {
|
76
96
|
reparented->nsDef = curr->next;
|
77
97
|
}
|
78
|
-
|
98
|
+
noko_xml_document_pin_namespace(curr, reparented->doc);
|
79
99
|
} else {
|
80
100
|
prev = curr;
|
81
101
|
}
|
@@ -83,29 +103,49 @@ static void relink_namespace(xmlNodePtr reparented)
|
|
83
103
|
}
|
84
104
|
}
|
85
105
|
|
106
|
+
/*
|
107
|
+
* Search our parents for an existing definition of current namespace,
|
108
|
+
* because the definition it's pointing to may have just been removed nsDef.
|
109
|
+
*
|
110
|
+
* And although that would technically probably be OK, I'd feel better if we
|
111
|
+
* referred to a namespace that's still present in a node's nsDef somewhere
|
112
|
+
* in the doc.
|
113
|
+
*/
|
114
|
+
if (reparented->ns) {
|
115
|
+
xmlNsPtr ns = xmlSearchNs(reparented->doc, reparented, reparented->ns->prefix);
|
116
|
+
if (ns
|
117
|
+
&& ns != reparented->ns
|
118
|
+
&& xmlStrEqual(ns->prefix, reparented->ns->prefix)
|
119
|
+
&& xmlStrEqual(ns->href, reparented->ns->href)
|
120
|
+
) {
|
121
|
+
xmlSetNs(reparented, ns);
|
122
|
+
}
|
123
|
+
}
|
124
|
+
|
86
125
|
/* Only walk all children if there actually is a namespace we need to */
|
87
126
|
/* reparent. */
|
88
|
-
if(NULL == reparented->ns) return;
|
127
|
+
if (NULL == reparented->ns) { return; }
|
89
128
|
|
90
129
|
/* When a node gets reparented, walk it's children to make sure that */
|
91
130
|
/* their namespaces are reparented as well. */
|
92
131
|
child = reparented->children;
|
93
|
-
while(NULL != child) {
|
132
|
+
while (NULL != child) {
|
94
133
|
relink_namespace(child);
|
95
134
|
child = child->next;
|
96
135
|
}
|
97
136
|
|
98
137
|
if (reparented->type == XML_ELEMENT_NODE) {
|
99
|
-
|
100
|
-
while(NULL !=
|
101
|
-
relink_namespace(
|
102
|
-
|
138
|
+
attr = reparented->properties;
|
139
|
+
while (NULL != attr) {
|
140
|
+
relink_namespace((xmlNodePtr)attr);
|
141
|
+
attr = attr->next;
|
103
142
|
}
|
104
143
|
}
|
105
144
|
}
|
106
145
|
|
107
146
|
/* :nodoc: */
|
108
|
-
static xmlNodePtr
|
147
|
+
static xmlNodePtr
|
148
|
+
xmlReplaceNodeWrapper(xmlNodePtr pivot, xmlNodePtr new_node)
|
109
149
|
{
|
110
150
|
xmlNodePtr retval ;
|
111
151
|
|
@@ -129,23 +169,97 @@ static xmlNodePtr xmlReplaceNodeWrapper(xmlNodePtr pivot, xmlNodePtr new_node)
|
|
129
169
|
}
|
130
170
|
|
131
171
|
/* :nodoc: */
|
132
|
-
static VALUE
|
172
|
+
static VALUE
|
173
|
+
reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_reparentee_func prf)
|
133
174
|
{
|
134
175
|
VALUE reparented_obj ;
|
135
|
-
xmlNodePtr reparentee, pivot, reparented, next_text, new_next_text ;
|
176
|
+
xmlNodePtr reparentee, original_reparentee, pivot, reparented, next_text, new_next_text, parent ;
|
177
|
+
int original_ns_prefix_is_default = 0 ;
|
136
178
|
|
137
|
-
if(!rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlNode))
|
179
|
+
if (!rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlNode)) {
|
138
180
|
rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node");
|
139
|
-
|
181
|
+
}
|
182
|
+
if (rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlDocument)) {
|
140
183
|
rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node");
|
184
|
+
}
|
141
185
|
|
142
186
|
Data_Get_Struct(reparentee_obj, xmlNode, reparentee);
|
143
187
|
Data_Get_Struct(pivot_obj, xmlNode, pivot);
|
144
188
|
|
145
|
-
|
146
|
-
|
189
|
+
/*
|
190
|
+
* Check if nodes given are appropriate to have a parent-child
|
191
|
+
* relationship, based on the DOM specification.
|
192
|
+
*
|
193
|
+
* cf. http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-1590626202
|
194
|
+
*/
|
195
|
+
if (prf == xmlAddChild) {
|
196
|
+
parent = pivot;
|
197
|
+
} else {
|
198
|
+
parent = pivot->parent;
|
199
|
+
}
|
200
|
+
|
201
|
+
if (parent) {
|
202
|
+
switch (parent->type) {
|
203
|
+
case XML_DOCUMENT_NODE:
|
204
|
+
case XML_HTML_DOCUMENT_NODE:
|
205
|
+
switch (reparentee->type) {
|
206
|
+
case XML_ELEMENT_NODE:
|
207
|
+
case XML_PI_NODE:
|
208
|
+
case XML_COMMENT_NODE:
|
209
|
+
case XML_DOCUMENT_TYPE_NODE:
|
210
|
+
/*
|
211
|
+
* The DOM specification says no to adding text-like nodes
|
212
|
+
* directly to a document, but we allow it for compatibility.
|
213
|
+
*/
|
214
|
+
case XML_TEXT_NODE:
|
215
|
+
case XML_CDATA_SECTION_NODE:
|
216
|
+
case XML_ENTITY_REF_NODE:
|
217
|
+
goto ok;
|
218
|
+
default:
|
219
|
+
break;
|
220
|
+
}
|
221
|
+
break;
|
222
|
+
case XML_DOCUMENT_FRAG_NODE:
|
223
|
+
case XML_ENTITY_REF_NODE:
|
224
|
+
case XML_ELEMENT_NODE:
|
225
|
+
switch (reparentee->type) {
|
226
|
+
case XML_ELEMENT_NODE:
|
227
|
+
case XML_PI_NODE:
|
228
|
+
case XML_COMMENT_NODE:
|
229
|
+
case XML_TEXT_NODE:
|
230
|
+
case XML_CDATA_SECTION_NODE:
|
231
|
+
case XML_ENTITY_REF_NODE:
|
232
|
+
goto ok;
|
233
|
+
default:
|
234
|
+
break;
|
235
|
+
}
|
236
|
+
break;
|
237
|
+
case XML_ATTRIBUTE_NODE:
|
238
|
+
switch (reparentee->type) {
|
239
|
+
case XML_TEXT_NODE:
|
240
|
+
case XML_ENTITY_REF_NODE:
|
241
|
+
goto ok;
|
242
|
+
default:
|
243
|
+
break;
|
244
|
+
}
|
245
|
+
break;
|
246
|
+
case XML_TEXT_NODE:
|
247
|
+
/*
|
248
|
+
* xmlAddChild() breaks the DOM specification in that it allows
|
249
|
+
* adding a text node to another, in which case text nodes are
|
250
|
+
* coalesced, but since our JRuby version does not support such
|
251
|
+
* operation, we should inhibit it.
|
252
|
+
*/
|
253
|
+
break;
|
254
|
+
default:
|
255
|
+
break;
|
256
|
+
}
|
257
|
+
|
258
|
+
rb_raise(rb_eArgError, "cannot reparent %s there", rb_obj_classname(reparentee_obj));
|
259
|
+
}
|
147
260
|
|
148
|
-
|
261
|
+
ok:
|
262
|
+
original_reparentee = reparentee;
|
149
263
|
|
150
264
|
if (reparentee->doc != pivot->doc || reparentee->type == XML_TEXT_NODE) {
|
151
265
|
/*
|
@@ -164,12 +278,46 @@ static VALUE reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_rep
|
|
164
278
|
* uninteresting libxml2 implementation detail). as a result, we cannot
|
165
279
|
* reparent the actual reparentee, so we reparent a duplicate.
|
166
280
|
*/
|
167
|
-
|
281
|
+
if (reparentee->type == XML_TEXT_NODE && reparentee->_private) {
|
282
|
+
/*
|
283
|
+
* additionally, since we know this C struct isn't going to be related to
|
284
|
+
* a Ruby object anymore, let's break the relationship on this end as
|
285
|
+
* well.
|
286
|
+
*
|
287
|
+
* this is not absolutely necessary unless libxml-ruby is also in effect,
|
288
|
+
* in which case its global callback `rxml_node_deregisterNode` will try
|
289
|
+
* to do things to our data.
|
290
|
+
*
|
291
|
+
* for more details on this particular (and particularly nasty) edge
|
292
|
+
* case, see:
|
293
|
+
*
|
294
|
+
* https://github.com/sparklemotion/nokogiri/issues/1426
|
295
|
+
*/
|
296
|
+
reparentee->_private = NULL ;
|
297
|
+
}
|
298
|
+
|
299
|
+
if (reparentee->ns != NULL && reparentee->ns->prefix == NULL) {
|
300
|
+
original_ns_prefix_is_default = 1;
|
301
|
+
}
|
302
|
+
|
303
|
+
noko_xml_document_pin_node(reparentee);
|
304
|
+
|
168
305
|
if (!(reparentee = xmlDocCopyNode(reparentee, pivot->doc, 1))) {
|
169
306
|
rb_raise(rb_eRuntimeError, "Could not reparent node (xmlDocCopyNode)");
|
170
307
|
}
|
308
|
+
|
309
|
+
if (original_ns_prefix_is_default && reparentee->ns != NULL && reparentee->ns->prefix != NULL) {
|
310
|
+
/*
|
311
|
+
* issue #391, where new node's prefix may become the string "default"
|
312
|
+
* see libxml2 tree.c xmlNewReconciliedNs which implements this behavior.
|
313
|
+
*/
|
314
|
+
xmlFree(DISCARD_CONST_QUAL_XMLCHAR(reparentee->ns->prefix));
|
315
|
+
reparentee->ns->prefix = NULL;
|
316
|
+
}
|
171
317
|
}
|
172
318
|
|
319
|
+
xmlUnlinkNode(original_reparentee);
|
320
|
+
|
173
321
|
if (prf != xmlAddPrevSibling && prf != xmlAddNextSibling
|
174
322
|
&& reparentee->type == XML_TEXT_NODE && pivot->next && pivot->next->type == XML_TEXT_NODE) {
|
175
323
|
/*
|
@@ -194,12 +342,12 @@ static VALUE reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_rep
|
|
194
342
|
new_next_text = xmlDocCopyNode(next_text, pivot->doc, 1) ;
|
195
343
|
|
196
344
|
xmlUnlinkNode(next_text);
|
197
|
-
|
345
|
+
noko_xml_document_pin_node(next_text);
|
198
346
|
|
199
347
|
xmlAddNextSibling(pivot, new_next_text);
|
200
348
|
}
|
201
349
|
|
202
|
-
if(!(reparented = (*prf)(pivot, reparentee))) {
|
350
|
+
if (!(reparented = (*prf)(pivot, reparentee))) {
|
203
351
|
rb_raise(rb_eRuntimeError, "Could not reparent node");
|
204
352
|
}
|
205
353
|
|
@@ -212,9 +360,9 @@ static VALUE reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_rep
|
|
212
360
|
|
213
361
|
relink_namespace(reparented);
|
214
362
|
|
215
|
-
reparented_obj =
|
363
|
+
reparented_obj = noko_xml_node_wrap(Qnil, reparented);
|
216
364
|
|
217
|
-
rb_funcall(reparented_obj,
|
365
|
+
rb_funcall(reparented_obj, id_decorate_bang, 0);
|
218
366
|
|
219
367
|
return reparented_obj ;
|
220
368
|
}
|
@@ -226,7 +374,8 @@ static VALUE reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_rep
|
|
226
374
|
*
|
227
375
|
* Get the document for this Node
|
228
376
|
*/
|
229
|
-
static VALUE
|
377
|
+
static VALUE
|
378
|
+
document(VALUE self)
|
230
379
|
{
|
231
380
|
xmlNodePtr node;
|
232
381
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -239,7 +388,8 @@ static VALUE document(VALUE self)
|
|
239
388
|
*
|
240
389
|
* Get the internal pointer number
|
241
390
|
*/
|
242
|
-
static VALUE
|
391
|
+
static VALUE
|
392
|
+
pointer_id(VALUE self)
|
243
393
|
{
|
244
394
|
xmlNodePtr node;
|
245
395
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -253,7 +403,8 @@ static VALUE pointer_id(VALUE self)
|
|
253
403
|
*
|
254
404
|
* Encode any special characters in +string+
|
255
405
|
*/
|
256
|
-
static VALUE
|
406
|
+
static VALUE
|
407
|
+
encode_special_chars(VALUE self, VALUE string)
|
257
408
|
{
|
258
409
|
xmlNodePtr node;
|
259
410
|
xmlChar *encoded;
|
@@ -261,9 +412,9 @@ static VALUE encode_special_chars(VALUE self, VALUE string)
|
|
261
412
|
|
262
413
|
Data_Get_Struct(self, xmlNode, node);
|
263
414
|
encoded = xmlEncodeSpecialChars(
|
264
|
-
|
265
|
-
|
266
|
-
|
415
|
+
node->doc,
|
416
|
+
(const xmlChar *)StringValueCStr(string)
|
417
|
+
);
|
267
418
|
|
268
419
|
encoded_str = NOKOGIRI_STR_NEW2(encoded);
|
269
420
|
xmlFree(encoded);
|
@@ -283,7 +434,8 @@ static VALUE encode_special_chars(VALUE self, VALUE string)
|
|
283
434
|
* doc.create_internal_subset("chapter", nil, "chapter.dtd")
|
284
435
|
* # => <!DOCTYPE chapter SYSTEM "chapter.dtd">
|
285
436
|
*/
|
286
|
-
static VALUE
|
437
|
+
static VALUE
|
438
|
+
create_internal_subset(VALUE self, VALUE name, VALUE external_id, VALUE system_id)
|
287
439
|
{
|
288
440
|
xmlNodePtr node;
|
289
441
|
xmlDocPtr doc;
|
@@ -293,19 +445,20 @@ static VALUE create_internal_subset(VALUE self, VALUE name, VALUE external_id, V
|
|
293
445
|
|
294
446
|
doc = node->doc;
|
295
447
|
|
296
|
-
if(xmlGetIntSubset(doc))
|
448
|
+
if (xmlGetIntSubset(doc)) {
|
297
449
|
rb_raise(rb_eRuntimeError, "Document already has an internal subset");
|
450
|
+
}
|
298
451
|
|
299
452
|
dtd = xmlCreateIntSubset(
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
453
|
+
doc,
|
454
|
+
NIL_P(name) ? NULL : (const xmlChar *)StringValueCStr(name),
|
455
|
+
NIL_P(external_id) ? NULL : (const xmlChar *)StringValueCStr(external_id),
|
456
|
+
NIL_P(system_id) ? NULL : (const xmlChar *)StringValueCStr(system_id)
|
457
|
+
);
|
305
458
|
|
306
|
-
if(!dtd) return Qnil;
|
459
|
+
if (!dtd) { return Qnil; }
|
307
460
|
|
308
|
-
return
|
461
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)dtd);
|
309
462
|
}
|
310
463
|
|
311
464
|
/*
|
@@ -314,7 +467,8 @@ static VALUE create_internal_subset(VALUE self, VALUE name, VALUE external_id, V
|
|
314
467
|
*
|
315
468
|
* Create an external subset
|
316
469
|
*/
|
317
|
-
static VALUE
|
470
|
+
static VALUE
|
471
|
+
create_external_subset(VALUE self, VALUE name, VALUE external_id, VALUE system_id)
|
318
472
|
{
|
319
473
|
xmlNodePtr node;
|
320
474
|
xmlDocPtr doc;
|
@@ -324,19 +478,20 @@ static VALUE create_external_subset(VALUE self, VALUE name, VALUE external_id, V
|
|
324
478
|
|
325
479
|
doc = node->doc;
|
326
480
|
|
327
|
-
if(doc->extSubset)
|
481
|
+
if (doc->extSubset) {
|
328
482
|
rb_raise(rb_eRuntimeError, "Document already has an external subset");
|
483
|
+
}
|
329
484
|
|
330
485
|
dtd = xmlNewDtd(
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
486
|
+
doc,
|
487
|
+
NIL_P(name) ? NULL : (const xmlChar *)StringValueCStr(name),
|
488
|
+
NIL_P(external_id) ? NULL : (const xmlChar *)StringValueCStr(external_id),
|
489
|
+
NIL_P(system_id) ? NULL : (const xmlChar *)StringValueCStr(system_id)
|
490
|
+
);
|
336
491
|
|
337
|
-
if(!dtd) return Qnil;
|
492
|
+
if (!dtd) { return Qnil; }
|
338
493
|
|
339
|
-
return
|
494
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)dtd);
|
340
495
|
}
|
341
496
|
|
342
497
|
/*
|
@@ -345,7 +500,8 @@ static VALUE create_external_subset(VALUE self, VALUE name, VALUE external_id, V
|
|
345
500
|
*
|
346
501
|
* Get the external subset
|
347
502
|
*/
|
348
|
-
static VALUE
|
503
|
+
static VALUE
|
504
|
+
external_subset(VALUE self)
|
349
505
|
{
|
350
506
|
xmlNodePtr node;
|
351
507
|
xmlDocPtr doc;
|
@@ -353,14 +509,14 @@ static VALUE external_subset(VALUE self)
|
|
353
509
|
|
354
510
|
Data_Get_Struct(self, xmlNode, node);
|
355
511
|
|
356
|
-
if(!node->doc) return Qnil;
|
512
|
+
if (!node->doc) { return Qnil; }
|
357
513
|
|
358
514
|
doc = node->doc;
|
359
515
|
dtd = doc->extSubset;
|
360
516
|
|
361
|
-
if(!dtd) return Qnil;
|
517
|
+
if (!dtd) { return Qnil; }
|
362
518
|
|
363
|
-
return
|
519
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)dtd);
|
364
520
|
}
|
365
521
|
|
366
522
|
/*
|
@@ -369,7 +525,8 @@ static VALUE external_subset(VALUE self)
|
|
369
525
|
*
|
370
526
|
* Get the internal subset
|
371
527
|
*/
|
372
|
-
static VALUE
|
528
|
+
static VALUE
|
529
|
+
internal_subset(VALUE self)
|
373
530
|
{
|
374
531
|
xmlNodePtr node;
|
375
532
|
xmlDocPtr doc;
|
@@ -377,39 +534,58 @@ static VALUE internal_subset(VALUE self)
|
|
377
534
|
|
378
535
|
Data_Get_Struct(self, xmlNode, node);
|
379
536
|
|
380
|
-
if(!node->doc) return Qnil;
|
537
|
+
if (!node->doc) { return Qnil; }
|
381
538
|
|
382
539
|
doc = node->doc;
|
383
540
|
dtd = xmlGetIntSubset(doc);
|
384
541
|
|
385
|
-
if(!dtd) return Qnil;
|
542
|
+
if (!dtd) { return Qnil; }
|
386
543
|
|
387
|
-
return
|
544
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)dtd);
|
388
545
|
}
|
389
546
|
|
390
547
|
/*
|
391
548
|
* call-seq:
|
392
549
|
* dup
|
550
|
+
* dup(depth)
|
551
|
+
* dup(depth, new_parent_doc)
|
393
552
|
*
|
394
|
-
* Copy this node.
|
395
|
-
*
|
553
|
+
* Copy this node.
|
554
|
+
* An optional depth may be passed in. 0 is a shallow copy, 1 (the default) is a deep copy.
|
555
|
+
* An optional new_parent_doc may also be passed in, which will be the new
|
556
|
+
* node's parent document. Defaults to the current node's document.
|
557
|
+
* current document.
|
396
558
|
*/
|
397
|
-
static VALUE
|
559
|
+
static VALUE
|
560
|
+
duplicate_node(int argc, VALUE *argv, VALUE self)
|
398
561
|
{
|
399
|
-
VALUE
|
562
|
+
VALUE r_level, r_new_parent_doc;
|
563
|
+
int level;
|
564
|
+
int n_args;
|
565
|
+
xmlDocPtr new_parent_doc;
|
400
566
|
xmlNodePtr node, dup;
|
401
567
|
|
402
|
-
if(rb_scan_args(argc, argv, "01", &level) == 0)
|
403
|
-
level = INT2NUM((long)1);
|
404
|
-
|
405
568
|
Data_Get_Struct(self, xmlNode, node);
|
406
569
|
|
407
|
-
|
408
|
-
|
570
|
+
n_args = rb_scan_args(argc, argv, "02", &r_level, &r_new_parent_doc);
|
571
|
+
|
572
|
+
if (n_args < 1) {
|
573
|
+
r_level = INT2NUM((long)1);
|
574
|
+
}
|
575
|
+
level = (int)NUM2INT(r_level);
|
576
|
+
|
577
|
+
if (n_args < 2) {
|
578
|
+
new_parent_doc = node->doc;
|
579
|
+
} else {
|
580
|
+
Data_Get_Struct(r_new_parent_doc, xmlDoc, new_parent_doc);
|
581
|
+
}
|
409
582
|
|
410
|
-
|
583
|
+
dup = xmlDocCopyNode(node, new_parent_doc, level);
|
584
|
+
if (dup == NULL) { return Qnil; }
|
411
585
|
|
412
|
-
|
586
|
+
noko_xml_document_pin_node(dup);
|
587
|
+
|
588
|
+
return noko_xml_node_wrap(rb_obj_class(self), dup);
|
413
589
|
}
|
414
590
|
|
415
591
|
/*
|
@@ -418,12 +594,13 @@ static VALUE duplicate_node(int argc, VALUE *argv, VALUE self)
|
|
418
594
|
*
|
419
595
|
* Unlink this node from its current context.
|
420
596
|
*/
|
421
|
-
static VALUE
|
597
|
+
static VALUE
|
598
|
+
unlink_node(VALUE self)
|
422
599
|
{
|
423
600
|
xmlNodePtr node;
|
424
601
|
Data_Get_Struct(self, xmlNode, node);
|
425
602
|
xmlUnlinkNode(node);
|
426
|
-
|
603
|
+
noko_xml_document_pin_node(node);
|
427
604
|
return self;
|
428
605
|
}
|
429
606
|
|
@@ -433,7 +610,8 @@ static VALUE unlink_node(VALUE self)
|
|
433
610
|
*
|
434
611
|
* Is this node blank?
|
435
612
|
*/
|
436
|
-
static VALUE
|
613
|
+
static VALUE
|
614
|
+
blank_eh(VALUE self)
|
437
615
|
{
|
438
616
|
xmlNodePtr node;
|
439
617
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -446,15 +624,16 @@ static VALUE blank_eh(VALUE self)
|
|
446
624
|
*
|
447
625
|
* Returns the next sibling node
|
448
626
|
*/
|
449
|
-
static VALUE
|
627
|
+
static VALUE
|
628
|
+
next_sibling(VALUE self)
|
450
629
|
{
|
451
630
|
xmlNodePtr node, sibling;
|
452
631
|
Data_Get_Struct(self, xmlNode, node);
|
453
632
|
|
454
633
|
sibling = node->next;
|
455
|
-
if(!sibling) return Qnil;
|
634
|
+
if (!sibling) { return Qnil; }
|
456
635
|
|
457
|
-
return
|
636
|
+
return noko_xml_node_wrap(Qnil, sibling) ;
|
458
637
|
}
|
459
638
|
|
460
639
|
/*
|
@@ -463,15 +642,16 @@ static VALUE next_sibling(VALUE self)
|
|
463
642
|
*
|
464
643
|
* Returns the previous sibling node
|
465
644
|
*/
|
466
|
-
static VALUE
|
645
|
+
static VALUE
|
646
|
+
previous_sibling(VALUE self)
|
467
647
|
{
|
468
648
|
xmlNodePtr node, sibling;
|
469
649
|
Data_Get_Struct(self, xmlNode, node);
|
470
650
|
|
471
651
|
sibling = node->prev;
|
472
|
-
if(!sibling) return Qnil;
|
652
|
+
if (!sibling) { return Qnil; }
|
473
653
|
|
474
|
-
return
|
654
|
+
return noko_xml_node_wrap(Qnil, sibling);
|
475
655
|
}
|
476
656
|
|
477
657
|
/*
|
@@ -480,15 +660,16 @@ static VALUE previous_sibling(VALUE self)
|
|
480
660
|
*
|
481
661
|
* Returns the next Nokogiri::XML::Element type sibling node.
|
482
662
|
*/
|
483
|
-
static VALUE
|
663
|
+
static VALUE
|
664
|
+
next_element(VALUE self)
|
484
665
|
{
|
485
666
|
xmlNodePtr node, sibling;
|
486
667
|
Data_Get_Struct(self, xmlNode, node);
|
487
668
|
|
488
669
|
sibling = xmlNextElementSibling(node);
|
489
|
-
if(!sibling) return Qnil;
|
670
|
+
if (!sibling) { return Qnil; }
|
490
671
|
|
491
|
-
return
|
672
|
+
return noko_xml_node_wrap(Qnil, sibling);
|
492
673
|
}
|
493
674
|
|
494
675
|
/*
|
@@ -497,7 +678,8 @@ static VALUE next_element(VALUE self)
|
|
497
678
|
*
|
498
679
|
* Returns the previous Nokogiri::XML::Element type sibling node.
|
499
680
|
*/
|
500
|
-
static VALUE
|
681
|
+
static VALUE
|
682
|
+
previous_element(VALUE self)
|
501
683
|
{
|
502
684
|
xmlNodePtr node, sibling;
|
503
685
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -506,24 +688,26 @@ static VALUE previous_element(VALUE self)
|
|
506
688
|
* note that we don't use xmlPreviousElementSibling here because it's buggy pre-2.7.7.
|
507
689
|
*/
|
508
690
|
sibling = node->prev;
|
509
|
-
if(!sibling) return Qnil;
|
691
|
+
if (!sibling) { return Qnil; }
|
510
692
|
|
511
|
-
while(sibling && sibling->type != XML_ELEMENT_NODE)
|
693
|
+
while (sibling && sibling->type != XML_ELEMENT_NODE) {
|
512
694
|
sibling = sibling->prev;
|
695
|
+
}
|
513
696
|
|
514
|
-
return sibling ?
|
697
|
+
return sibling ? noko_xml_node_wrap(Qnil, sibling) : Qnil ;
|
515
698
|
}
|
516
699
|
|
517
700
|
/* :nodoc: */
|
518
|
-
static VALUE
|
701
|
+
static VALUE
|
702
|
+
replace(VALUE self, VALUE new_node)
|
519
703
|
{
|
520
|
-
|
704
|
+
VALUE reparent = reparent_node_with(self, new_node, xmlReplaceNodeWrapper);
|
521
705
|
|
522
|
-
|
523
|
-
|
524
|
-
|
706
|
+
xmlNodePtr pivot;
|
707
|
+
Data_Get_Struct(self, xmlNode, pivot);
|
708
|
+
noko_xml_document_pin_node(pivot);
|
525
709
|
|
526
|
-
|
710
|
+
return reparent;
|
527
711
|
}
|
528
712
|
|
529
713
|
/*
|
@@ -532,7 +716,8 @@ static VALUE replace(VALUE self, VALUE new_node)
|
|
532
716
|
*
|
533
717
|
* Get the list of children for this node as a NodeSet
|
534
718
|
*/
|
535
|
-
static VALUE
|
719
|
+
static VALUE
|
720
|
+
children(VALUE self)
|
536
721
|
{
|
537
722
|
xmlNodePtr node;
|
538
723
|
xmlNodePtr child;
|
@@ -547,15 +732,15 @@ static VALUE children(VALUE self)
|
|
547
732
|
|
548
733
|
document = DOC_RUBY_OBJECT(node->doc);
|
549
734
|
|
550
|
-
if(!child) return
|
735
|
+
if (!child) { return noko_xml_node_set_wrap(set, document); }
|
551
736
|
|
552
737
|
child = child->next;
|
553
|
-
while(NULL != child) {
|
738
|
+
while (NULL != child) {
|
554
739
|
xmlXPathNodeSetAddUnique(set, child);
|
555
740
|
child = child->next;
|
556
741
|
}
|
557
742
|
|
558
|
-
node_set =
|
743
|
+
node_set = noko_xml_node_set_wrap(set, document);
|
559
744
|
|
560
745
|
return node_set;
|
561
746
|
}
|
@@ -571,7 +756,8 @@ static VALUE children(VALUE self)
|
|
571
756
|
*
|
572
757
|
* @doc.root.element_children.all? { |x| x.element? } # => true
|
573
758
|
*/
|
574
|
-
static VALUE
|
759
|
+
static VALUE
|
760
|
+
element_children(VALUE self)
|
575
761
|
{
|
576
762
|
xmlNodePtr node;
|
577
763
|
xmlNodePtr child;
|
@@ -586,15 +772,15 @@ static VALUE element_children(VALUE self)
|
|
586
772
|
|
587
773
|
document = DOC_RUBY_OBJECT(node->doc);
|
588
774
|
|
589
|
-
if(!child) return
|
775
|
+
if (!child) { return noko_xml_node_set_wrap(set, document); }
|
590
776
|
|
591
777
|
child = xmlNextElementSibling(child);
|
592
|
-
while(NULL != child) {
|
778
|
+
while (NULL != child) {
|
593
779
|
xmlXPathNodeSetAddUnique(set, child);
|
594
780
|
child = xmlNextElementSibling(child);
|
595
781
|
}
|
596
782
|
|
597
|
-
node_set =
|
783
|
+
node_set = noko_xml_node_set_wrap(set, document);
|
598
784
|
|
599
785
|
return node_set;
|
600
786
|
}
|
@@ -605,15 +791,16 @@ static VALUE element_children(VALUE self)
|
|
605
791
|
*
|
606
792
|
* Returns the child node
|
607
793
|
*/
|
608
|
-
static VALUE
|
794
|
+
static VALUE
|
795
|
+
child(VALUE self)
|
609
796
|
{
|
610
797
|
xmlNodePtr node, child;
|
611
798
|
Data_Get_Struct(self, xmlNode, node);
|
612
799
|
|
613
800
|
child = node->children;
|
614
|
-
if(!child) return Qnil;
|
801
|
+
if (!child) { return Qnil; }
|
615
802
|
|
616
|
-
return
|
803
|
+
return noko_xml_node_wrap(Qnil, child);
|
617
804
|
}
|
618
805
|
|
619
806
|
/*
|
@@ -626,15 +813,16 @@ static VALUE child(VALUE self)
|
|
626
813
|
*
|
627
814
|
* @doc.root.first_element_child.element? # => true
|
628
815
|
*/
|
629
|
-
static VALUE
|
816
|
+
static VALUE
|
817
|
+
first_element_child(VALUE self)
|
630
818
|
{
|
631
819
|
xmlNodePtr node, child;
|
632
820
|
Data_Get_Struct(self, xmlNode, node);
|
633
821
|
|
634
822
|
child = xmlFirstElementChild(node);
|
635
|
-
if(!child) return Qnil;
|
823
|
+
if (!child) { return Qnil; }
|
636
824
|
|
637
|
-
return
|
825
|
+
return noko_xml_node_wrap(Qnil, child);
|
638
826
|
}
|
639
827
|
|
640
828
|
/*
|
@@ -647,15 +835,16 @@ static VALUE first_element_child(VALUE self)
|
|
647
835
|
*
|
648
836
|
* @doc.root.last_element_child.element? # => true
|
649
837
|
*/
|
650
|
-
static VALUE
|
838
|
+
static VALUE
|
839
|
+
last_element_child(VALUE self)
|
651
840
|
{
|
652
841
|
xmlNodePtr node, child;
|
653
842
|
Data_Get_Struct(self, xmlNode, node);
|
654
843
|
|
655
844
|
child = xmlLastElementChild(node);
|
656
|
-
if(!child) return Qnil;
|
845
|
+
if (!child) { return Qnil; }
|
657
846
|
|
658
|
-
return
|
847
|
+
return noko_xml_node_wrap(Qnil, child);
|
659
848
|
}
|
660
849
|
|
661
850
|
/*
|
@@ -664,12 +853,14 @@ static VALUE last_element_child(VALUE self)
|
|
664
853
|
*
|
665
854
|
* Returns true if +attribute+ is set
|
666
855
|
*/
|
667
|
-
static VALUE
|
856
|
+
static VALUE
|
857
|
+
key_eh(VALUE self, VALUE attribute)
|
668
858
|
{
|
669
859
|
xmlNodePtr node;
|
670
860
|
Data_Get_Struct(self, xmlNode, node);
|
671
|
-
if(xmlHasProp(node, (xmlChar *)
|
861
|
+
if (xmlHasProp(node, (xmlChar *)StringValueCStr(attribute))) {
|
672
862
|
return Qtrue;
|
863
|
+
}
|
673
864
|
return Qfalse;
|
674
865
|
}
|
675
866
|
|
@@ -679,13 +870,15 @@ static VALUE key_eh(VALUE self, VALUE attribute)
|
|
679
870
|
*
|
680
871
|
* Returns true if +attribute+ is set with +namespace+
|
681
872
|
*/
|
682
|
-
static VALUE
|
873
|
+
static VALUE
|
874
|
+
namespaced_key_eh(VALUE self, VALUE attribute, VALUE namespace)
|
683
875
|
{
|
684
876
|
xmlNodePtr node;
|
685
877
|
Data_Get_Struct(self, xmlNode, node);
|
686
|
-
if(xmlHasNsProp(node, (xmlChar *)
|
687
|
-
|
878
|
+
if (xmlHasNsProp(node, (xmlChar *)StringValueCStr(attribute),
|
879
|
+
NIL_P(namespace) ? NULL : (xmlChar *)StringValueCStr(namespace))) {
|
688
880
|
return Qtrue;
|
881
|
+
}
|
689
882
|
return Qfalse;
|
690
883
|
}
|
691
884
|
|
@@ -695,7 +888,8 @@ static VALUE namespaced_key_eh(VALUE self, VALUE attribute, VALUE namespace)
|
|
695
888
|
*
|
696
889
|
* Set the +property+ to +value+
|
697
890
|
*/
|
698
|
-
static VALUE
|
891
|
+
static VALUE
|
892
|
+
set(VALUE self, VALUE property, VALUE value)
|
699
893
|
{
|
700
894
|
xmlNodePtr node, cur;
|
701
895
|
xmlAttrPtr prop;
|
@@ -707,20 +901,21 @@ static VALUE set(VALUE self, VALUE property, VALUE value)
|
|
707
901
|
*
|
708
902
|
* We can avoid this by unlinking these nodes first.
|
709
903
|
*/
|
710
|
-
if (node->type != XML_ELEMENT_NODE)
|
711
|
-
return(Qnil);
|
712
|
-
|
904
|
+
if (node->type != XML_ELEMENT_NODE) {
|
905
|
+
return (Qnil);
|
906
|
+
}
|
907
|
+
prop = xmlHasProp(node, (xmlChar *)StringValueCStr(property));
|
713
908
|
if (prop && prop->children) {
|
714
909
|
for (cur = prop->children; cur; cur = cur->next) {
|
715
910
|
if (cur->_private) {
|
716
|
-
|
911
|
+
noko_xml_document_pin_node(cur);
|
717
912
|
xmlUnlinkNode(cur);
|
718
913
|
}
|
719
914
|
}
|
720
915
|
}
|
721
916
|
|
722
|
-
xmlSetProp(node, (xmlChar *)
|
723
|
-
|
917
|
+
xmlSetProp(node, (xmlChar *)StringValueCStr(property),
|
918
|
+
(xmlChar *)StringValueCStr(value));
|
724
919
|
|
725
920
|
return value;
|
726
921
|
}
|
@@ -731,40 +926,44 @@ static VALUE set(VALUE self, VALUE property, VALUE value)
|
|
731
926
|
*
|
732
927
|
* Get the value for +attribute+
|
733
928
|
*/
|
734
|
-
static VALUE
|
929
|
+
static VALUE
|
930
|
+
get(VALUE self, VALUE rattribute)
|
735
931
|
{
|
736
932
|
xmlNodePtr node;
|
737
|
-
xmlChar*
|
738
|
-
VALUE rvalue
|
739
|
-
|
740
|
-
|
933
|
+
xmlChar *value = 0;
|
934
|
+
VALUE rvalue;
|
935
|
+
xmlChar *colon;
|
936
|
+
xmlChar *attribute, *attr_name, *prefix;
|
741
937
|
xmlNsPtr ns;
|
742
938
|
|
743
|
-
if (NIL_P(rattribute)) return Qnil;
|
939
|
+
if (NIL_P(rattribute)) { return Qnil; }
|
744
940
|
|
745
941
|
Data_Get_Struct(self, xmlNode, node);
|
746
|
-
attribute =
|
942
|
+
attribute = xmlCharStrdup(StringValueCStr(rattribute));
|
747
943
|
|
748
|
-
colon =
|
944
|
+
colon = DISCARD_CONST_QUAL_XMLCHAR(xmlStrchr(attribute, (const xmlChar)':'));
|
749
945
|
if (colon) {
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
946
|
+
/* split the attribute string into separate prefix and name by
|
947
|
+
* null-terminating the prefix at the colon */
|
948
|
+
prefix = attribute;
|
949
|
+
attr_name = colon + 1;
|
950
|
+
(*colon) = 0;
|
951
|
+
|
952
|
+
ns = xmlSearchNs(node->doc, node, prefix);
|
754
953
|
if (ns) {
|
755
|
-
value = xmlGetNsProp(node,
|
954
|
+
value = xmlGetNsProp(node, attr_name, ns->href);
|
756
955
|
} else {
|
757
|
-
value = xmlGetProp(node, (xmlChar*)
|
956
|
+
value = xmlGetProp(node, (xmlChar *)StringValueCStr(rattribute));
|
758
957
|
}
|
759
958
|
} else {
|
760
|
-
value = xmlGetNoNsProp(node,
|
959
|
+
value = xmlGetNoNsProp(node, attribute);
|
761
960
|
}
|
762
961
|
|
763
|
-
|
764
|
-
if (!value) return Qnil;
|
962
|
+
xmlFree((void *)attribute);
|
963
|
+
if (!value) { return Qnil; }
|
765
964
|
|
766
965
|
rvalue = NOKOGIRI_STR_NEW2(value);
|
767
|
-
xmlFree(value);
|
966
|
+
xmlFree((void *)value);
|
768
967
|
|
769
968
|
return rvalue ;
|
770
969
|
}
|
@@ -775,15 +974,17 @@ static VALUE get(VALUE self, VALUE rattribute)
|
|
775
974
|
*
|
776
975
|
* Set the namespace to +namespace+
|
777
976
|
*/
|
778
|
-
static VALUE
|
977
|
+
static VALUE
|
978
|
+
set_namespace(VALUE self, VALUE namespace)
|
779
979
|
{
|
780
980
|
xmlNodePtr node;
|
781
981
|
xmlNsPtr ns = NULL;
|
782
982
|
|
783
983
|
Data_Get_Struct(self, xmlNode, node);
|
784
984
|
|
785
|
-
if(!NIL_P(namespace))
|
985
|
+
if (!NIL_P(namespace)) {
|
786
986
|
Data_Get_Struct(namespace, xmlNs, ns);
|
987
|
+
}
|
787
988
|
|
788
989
|
xmlSetNs(node, ns);
|
789
990
|
|
@@ -796,15 +997,16 @@ static VALUE set_namespace(VALUE self, VALUE namespace)
|
|
796
997
|
*
|
797
998
|
* Get the attribute node with +name+
|
798
999
|
*/
|
799
|
-
static VALUE
|
1000
|
+
static VALUE
|
1001
|
+
attr(VALUE self, VALUE name)
|
800
1002
|
{
|
801
1003
|
xmlNodePtr node;
|
802
1004
|
xmlAttrPtr prop;
|
803
1005
|
Data_Get_Struct(self, xmlNode, node);
|
804
|
-
prop = xmlHasProp(node, (xmlChar *)
|
1006
|
+
prop = xmlHasProp(node, (xmlChar *)StringValueCStr(name));
|
805
1007
|
|
806
|
-
if(! prop) return Qnil;
|
807
|
-
return
|
1008
|
+
if (! prop) { return Qnil; }
|
1009
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)prop);
|
808
1010
|
}
|
809
1011
|
|
810
1012
|
/*
|
@@ -813,36 +1015,32 @@ static VALUE attr(VALUE self, VALUE name)
|
|
813
1015
|
*
|
814
1016
|
* Get the attribute node with +name+ and +namespace+
|
815
1017
|
*/
|
816
|
-
static VALUE
|
1018
|
+
static VALUE
|
1019
|
+
attribute_with_ns(VALUE self, VALUE name, VALUE namespace)
|
817
1020
|
{
|
818
1021
|
xmlNodePtr node;
|
819
1022
|
xmlAttrPtr prop;
|
820
1023
|
Data_Get_Struct(self, xmlNode, node);
|
821
|
-
prop = xmlHasNsProp(node, (xmlChar *)
|
822
|
-
|
1024
|
+
prop = xmlHasNsProp(node, (xmlChar *)StringValueCStr(name),
|
1025
|
+
NIL_P(namespace) ? NULL : (xmlChar *)StringValueCStr(namespace));
|
823
1026
|
|
824
|
-
if(! prop) return Qnil;
|
825
|
-
return
|
1027
|
+
if (! prop) { return Qnil; }
|
1028
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)prop);
|
826
1029
|
}
|
827
1030
|
|
828
1031
|
/*
|
829
|
-
*
|
830
|
-
*
|
831
|
-
*
|
832
|
-
* returns a list containing the Node attributes.
|
1032
|
+
* @overload attribute_nodes()
|
1033
|
+
* Get the attributes for a Node
|
1034
|
+
* @return [Array<Nokogiri::XML::Attr>] containing the Node's attributes.
|
833
1035
|
*/
|
834
|
-
static VALUE
|
1036
|
+
static VALUE
|
1037
|
+
attribute_nodes(VALUE rb_node)
|
835
1038
|
{
|
836
|
-
|
837
|
-
xmlNodePtr node;
|
838
|
-
VALUE attr;
|
1039
|
+
xmlNodePtr c_node;
|
839
1040
|
|
840
|
-
|
1041
|
+
Data_Get_Struct(rb_node, xmlNode, c_node);
|
841
1042
|
|
842
|
-
|
843
|
-
Nokogiri_xml_node_properties(node, attr);
|
844
|
-
|
845
|
-
return attr ;
|
1043
|
+
return noko_xml_node_attrs(c_node);
|
846
1044
|
}
|
847
1045
|
|
848
1046
|
|
@@ -850,16 +1048,18 @@ static VALUE attribute_nodes(VALUE self)
|
|
850
1048
|
* call-seq:
|
851
1049
|
* namespace()
|
852
1050
|
*
|
853
|
-
* returns the
|
854
|
-
*
|
1051
|
+
* returns the namespace of the element or attribute node as a Namespace
|
1052
|
+
* object, or nil if there is no namespace for the element or attribute.
|
855
1053
|
*/
|
856
|
-
static VALUE
|
1054
|
+
static VALUE
|
1055
|
+
noko_xml_node_namespace(VALUE rb_node)
|
857
1056
|
{
|
858
|
-
xmlNodePtr
|
859
|
-
Data_Get_Struct(
|
1057
|
+
xmlNodePtr c_node ;
|
1058
|
+
Data_Get_Struct(rb_node, xmlNode, c_node);
|
860
1059
|
|
861
|
-
if (
|
862
|
-
return
|
1060
|
+
if (c_node->ns) {
|
1061
|
+
return noko_xml_namespace_wrap(c_node->ns, c_node->doc);
|
1062
|
+
}
|
863
1063
|
|
864
1064
|
return Qnil ;
|
865
1065
|
}
|
@@ -870,27 +1070,27 @@ static VALUE namespace(VALUE self)
|
|
870
1070
|
*
|
871
1071
|
* returns namespaces defined on self element directly, as an array of Namespace objects. Includes both a default namespace (as in"xmlns="), and prefixed namespaces (as in "xmlns:prefix=").
|
872
1072
|
*/
|
873
|
-
static VALUE
|
1073
|
+
static VALUE
|
1074
|
+
namespace_definitions(VALUE rb_node)
|
874
1075
|
{
|
875
1076
|
/* this code in the mode of xmlHasProp() */
|
876
|
-
xmlNodePtr
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
Data_Get_Struct(self, xmlNode, node);
|
1077
|
+
xmlNodePtr c_node ;
|
1078
|
+
xmlNsPtr c_namespace;
|
1079
|
+
VALUE definitions = rb_ary_new();
|
881
1080
|
|
882
|
-
|
1081
|
+
Data_Get_Struct(rb_node, xmlNode, c_node);
|
883
1082
|
|
884
|
-
|
885
|
-
|
886
|
-
|
1083
|
+
c_namespace = c_node->nsDef;
|
1084
|
+
if (!c_namespace) {
|
1085
|
+
return definitions;
|
1086
|
+
}
|
887
1087
|
|
888
|
-
while(
|
889
|
-
rb_ary_push(
|
890
|
-
|
1088
|
+
while (c_namespace != NULL) {
|
1089
|
+
rb_ary_push(definitions, noko_xml_namespace_wrap(c_namespace, c_node->doc));
|
1090
|
+
c_namespace = c_namespace->next;
|
891
1091
|
}
|
892
1092
|
|
893
|
-
return
|
1093
|
+
return definitions;
|
894
1094
|
}
|
895
1095
|
|
896
1096
|
/*
|
@@ -902,26 +1102,27 @@ static VALUE namespace_definitions(VALUE self)
|
|
902
1102
|
* namespaces ("xmlns=" style) for self are included in this array; Default
|
903
1103
|
* namespaces for ancestors, however, are not. See also #namespaces
|
904
1104
|
*/
|
905
|
-
static VALUE
|
1105
|
+
static VALUE
|
1106
|
+
namespace_scopes(VALUE rb_node)
|
906
1107
|
{
|
907
|
-
xmlNodePtr
|
908
|
-
|
909
|
-
|
1108
|
+
xmlNodePtr c_node ;
|
1109
|
+
xmlNsPtr *namespaces;
|
1110
|
+
VALUE scopes = rb_ary_new();
|
910
1111
|
int j;
|
911
1112
|
|
912
|
-
Data_Get_Struct(
|
913
|
-
|
914
|
-
list = rb_ary_new();
|
915
|
-
ns_list = xmlGetNsList(node->doc, node);
|
1113
|
+
Data_Get_Struct(rb_node, xmlNode, c_node);
|
916
1114
|
|
917
|
-
|
1115
|
+
namespaces = xmlGetNsList(c_node->doc, c_node);
|
1116
|
+
if (!namespaces) {
|
1117
|
+
return scopes;
|
1118
|
+
}
|
918
1119
|
|
919
|
-
for (j = 0 ;
|
920
|
-
rb_ary_push(
|
1120
|
+
for (j = 0 ; namespaces[j] != NULL ; ++j) {
|
1121
|
+
rb_ary_push(scopes, noko_xml_namespace_wrap(namespaces[j], c_node->doc));
|
921
1122
|
}
|
922
1123
|
|
923
|
-
xmlFree(
|
924
|
-
return
|
1124
|
+
xmlFree(namespaces);
|
1125
|
+
return scopes;
|
925
1126
|
}
|
926
1127
|
|
927
1128
|
/*
|
@@ -930,7 +1131,8 @@ static VALUE namespace_scopes(VALUE self)
|
|
930
1131
|
*
|
931
1132
|
* Get the type for this Node
|
932
1133
|
*/
|
933
|
-
static VALUE
|
1134
|
+
static VALUE
|
1135
|
+
node_type(VALUE self)
|
934
1136
|
{
|
935
1137
|
xmlNodePtr node;
|
936
1138
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -943,7 +1145,8 @@ static VALUE node_type(VALUE self)
|
|
943
1145
|
*
|
944
1146
|
* Set the content for this Node
|
945
1147
|
*/
|
946
|
-
static VALUE
|
1148
|
+
static VALUE
|
1149
|
+
set_native_content(VALUE self, VALUE content)
|
947
1150
|
{
|
948
1151
|
xmlNodePtr node, child, next ;
|
949
1152
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -952,11 +1155,11 @@ static VALUE native_content(VALUE self, VALUE content)
|
|
952
1155
|
while (NULL != child) {
|
953
1156
|
next = child->next ;
|
954
1157
|
xmlUnlinkNode(child) ;
|
955
|
-
|
1158
|
+
noko_xml_document_pin_node(child);
|
956
1159
|
child = next ;
|
957
1160
|
}
|
958
1161
|
|
959
|
-
xmlNodeSetContent(node, (xmlChar *)
|
1162
|
+
xmlNodeSetContent(node, (xmlChar *)StringValueCStr(content));
|
960
1163
|
return content;
|
961
1164
|
}
|
962
1165
|
|
@@ -964,17 +1167,19 @@ static VALUE native_content(VALUE self, VALUE content)
|
|
964
1167
|
* call-seq:
|
965
1168
|
* content
|
966
1169
|
*
|
967
|
-
* Returns the content for this Node
|
1170
|
+
* Returns the plaintext content for this Node. Note that entities will always
|
1171
|
+
* be expanded in the returned string.
|
968
1172
|
*/
|
969
|
-
static VALUE
|
1173
|
+
static VALUE
|
1174
|
+
get_native_content(VALUE self)
|
970
1175
|
{
|
971
1176
|
xmlNodePtr node;
|
972
|
-
xmlChar *
|
1177
|
+
xmlChar *content;
|
973
1178
|
|
974
1179
|
Data_Get_Struct(self, xmlNode, node);
|
975
1180
|
|
976
1181
|
content = xmlNodeGetContent(node);
|
977
|
-
if(content) {
|
1182
|
+
if (content) {
|
978
1183
|
VALUE rval = NOKOGIRI_STR_NEW2(content);
|
979
1184
|
xmlFree(content);
|
980
1185
|
return rval;
|
@@ -982,8 +1187,55 @@ static VALUE get_content(VALUE self)
|
|
982
1187
|
return Qnil;
|
983
1188
|
}
|
984
1189
|
|
1190
|
+
/*
|
1191
|
+
* call-seq:
|
1192
|
+
* lang=
|
1193
|
+
*
|
1194
|
+
* Set the language of a node, i.e. the values of the xml:lang attribute.
|
1195
|
+
*/
|
1196
|
+
static VALUE
|
1197
|
+
set_lang(VALUE self_rb, VALUE lang_rb)
|
1198
|
+
{
|
1199
|
+
xmlNodePtr self ;
|
1200
|
+
xmlChar *lang ;
|
1201
|
+
|
1202
|
+
Data_Get_Struct(self_rb, xmlNode, self);
|
1203
|
+
lang = (xmlChar *)StringValueCStr(lang_rb);
|
1204
|
+
|
1205
|
+
xmlNodeSetLang(self, lang);
|
1206
|
+
|
1207
|
+
return Qnil ;
|
1208
|
+
}
|
1209
|
+
|
1210
|
+
/*
|
1211
|
+
* call-seq:
|
1212
|
+
* lang
|
1213
|
+
*
|
1214
|
+
* Searches the language of a node, i.e. the values of the xml:lang attribute or
|
1215
|
+
* the one carried by the nearest ancestor.
|
1216
|
+
*/
|
1217
|
+
static VALUE
|
1218
|
+
get_lang(VALUE self_rb)
|
1219
|
+
{
|
1220
|
+
xmlNodePtr self ;
|
1221
|
+
xmlChar *lang ;
|
1222
|
+
VALUE lang_rb ;
|
1223
|
+
|
1224
|
+
Data_Get_Struct(self_rb, xmlNode, self);
|
1225
|
+
|
1226
|
+
lang = xmlNodeGetLang(self);
|
1227
|
+
if (lang) {
|
1228
|
+
lang_rb = NOKOGIRI_STR_NEW2(lang);
|
1229
|
+
xmlFree(lang);
|
1230
|
+
return lang_rb ;
|
1231
|
+
}
|
1232
|
+
|
1233
|
+
return Qnil ;
|
1234
|
+
}
|
1235
|
+
|
985
1236
|
/* :nodoc: */
|
986
|
-
static VALUE
|
1237
|
+
static VALUE
|
1238
|
+
add_child(VALUE self, VALUE new_child)
|
987
1239
|
{
|
988
1240
|
return reparent_node_with(self, new_child, xmlAddChild);
|
989
1241
|
}
|
@@ -994,15 +1246,16 @@ static VALUE add_child(VALUE self, VALUE new_child)
|
|
994
1246
|
*
|
995
1247
|
* Get the parent Node for this Node
|
996
1248
|
*/
|
997
|
-
static VALUE
|
1249
|
+
static VALUE
|
1250
|
+
get_parent(VALUE self)
|
998
1251
|
{
|
999
1252
|
xmlNodePtr node, parent;
|
1000
1253
|
Data_Get_Struct(self, xmlNode, node);
|
1001
1254
|
|
1002
1255
|
parent = node->parent;
|
1003
|
-
if(!parent) return Qnil;
|
1256
|
+
if (!parent) { return Qnil; }
|
1004
1257
|
|
1005
|
-
return
|
1258
|
+
return noko_xml_node_wrap(Qnil, parent) ;
|
1006
1259
|
}
|
1007
1260
|
|
1008
1261
|
/*
|
@@ -1011,11 +1264,12 @@ static VALUE get_parent(VALUE self)
|
|
1011
1264
|
*
|
1012
1265
|
* Set the name for this Node
|
1013
1266
|
*/
|
1014
|
-
static VALUE
|
1267
|
+
static VALUE
|
1268
|
+
set_name(VALUE self, VALUE new_name)
|
1015
1269
|
{
|
1016
1270
|
xmlNodePtr node;
|
1017
1271
|
Data_Get_Struct(self, xmlNode, node);
|
1018
|
-
xmlNodeSetName(node, (xmlChar*)
|
1272
|
+
xmlNodeSetName(node, (xmlChar *)StringValueCStr(new_name));
|
1019
1273
|
return new_name;
|
1020
1274
|
}
|
1021
1275
|
|
@@ -1025,12 +1279,14 @@ static VALUE set_name(VALUE self, VALUE new_name)
|
|
1025
1279
|
*
|
1026
1280
|
* Returns the name for this Node
|
1027
1281
|
*/
|
1028
|
-
static VALUE
|
1282
|
+
static VALUE
|
1283
|
+
get_name(VALUE self)
|
1029
1284
|
{
|
1030
1285
|
xmlNodePtr node;
|
1031
1286
|
Data_Get_Struct(self, xmlNode, node);
|
1032
|
-
if(node->name)
|
1287
|
+
if (node->name) {
|
1033
1288
|
return NOKOGIRI_STR_NEW2(node->name);
|
1289
|
+
}
|
1034
1290
|
return Qnil;
|
1035
1291
|
}
|
1036
1292
|
|
@@ -1040,28 +1296,39 @@ static VALUE get_name(VALUE self)
|
|
1040
1296
|
*
|
1041
1297
|
* Returns the path associated with this Node
|
1042
1298
|
*/
|
1043
|
-
static VALUE
|
1299
|
+
static VALUE
|
1300
|
+
noko_xml_node_path(VALUE rb_node)
|
1044
1301
|
{
|
1045
|
-
xmlNodePtr
|
1046
|
-
xmlChar *
|
1302
|
+
xmlNodePtr c_node;
|
1303
|
+
xmlChar *c_path ;
|
1047
1304
|
VALUE rval;
|
1048
1305
|
|
1049
|
-
Data_Get_Struct(
|
1306
|
+
Data_Get_Struct(rb_node, xmlNode, c_node);
|
1307
|
+
|
1308
|
+
c_path = xmlGetNodePath(c_node);
|
1309
|
+
if (c_path == NULL) {
|
1310
|
+
// see https://github.com/sparklemotion/nokogiri/issues/2250
|
1311
|
+
// this behavior is clearly undesirable, but is what libxml <= 2.9.10 returned, and so we
|
1312
|
+
// do this for now to preserve the behavior across libxml2 versions.
|
1313
|
+
rval = NOKOGIRI_STR_NEW2("?");
|
1314
|
+
} else {
|
1315
|
+
rval = NOKOGIRI_STR_NEW2(c_path);
|
1316
|
+
xmlFree(c_path);
|
1317
|
+
}
|
1050
1318
|
|
1051
|
-
path = xmlGetNodePath(node);
|
1052
|
-
rval = NOKOGIRI_STR_NEW2(path);
|
1053
|
-
xmlFree(path);
|
1054
1319
|
return rval ;
|
1055
1320
|
}
|
1056
1321
|
|
1057
1322
|
/* :nodoc: */
|
1058
|
-
static VALUE
|
1323
|
+
static VALUE
|
1324
|
+
add_next_sibling(VALUE self, VALUE new_sibling)
|
1059
1325
|
{
|
1060
1326
|
return reparent_node_with(self, new_sibling, xmlAddNextSibling) ;
|
1061
1327
|
}
|
1062
1328
|
|
1063
1329
|
/* :nodoc: */
|
1064
|
-
static VALUE
|
1330
|
+
static VALUE
|
1331
|
+
add_previous_sibling(VALUE self, VALUE new_sibling)
|
1065
1332
|
{
|
1066
1333
|
return reparent_node_with(self, new_sibling, xmlAddPrevSibling) ;
|
1067
1334
|
}
|
@@ -1072,15 +1339,17 @@ static VALUE add_previous_sibling(VALUE self, VALUE new_sibling)
|
|
1072
1339
|
*
|
1073
1340
|
* Write this Node to +io+ with +encoding+ and +options+
|
1074
1341
|
*/
|
1075
|
-
static VALUE
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1342
|
+
static VALUE
|
1343
|
+
native_write_to(
|
1344
|
+
VALUE self,
|
1345
|
+
VALUE io,
|
1346
|
+
VALUE encoding,
|
1347
|
+
VALUE indent_string,
|
1348
|
+
VALUE options
|
1349
|
+
)
|
1350
|
+
{
|
1082
1351
|
xmlNodePtr node;
|
1083
|
-
const char *
|
1352
|
+
const char *before_indent;
|
1084
1353
|
xmlSaveCtxtPtr savectx;
|
1085
1354
|
|
1086
1355
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -1089,15 +1358,15 @@ static VALUE native_write_to(
|
|
1089
1358
|
|
1090
1359
|
before_indent = xmlTreeIndentString;
|
1091
1360
|
|
1092
|
-
xmlTreeIndentString =
|
1361
|
+
xmlTreeIndentString = StringValueCStr(indent_string);
|
1093
1362
|
|
1094
1363
|
savectx = xmlSaveToIO(
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1364
|
+
(xmlOutputWriteCallback)noko_io_write,
|
1365
|
+
(xmlOutputCloseCallback)noko_io_close,
|
1366
|
+
(void *)io,
|
1367
|
+
RTEST(encoding) ? StringValueCStr(encoding) : NULL,
|
1368
|
+
(int)NUM2INT(options)
|
1369
|
+
);
|
1101
1370
|
|
1102
1371
|
xmlSaveTree(savectx, node);
|
1103
1372
|
xmlSaveClose(savectx);
|
@@ -1112,7 +1381,8 @@ static VALUE native_write_to(
|
|
1112
1381
|
*
|
1113
1382
|
* Returns the line for this Node
|
1114
1383
|
*/
|
1115
|
-
static VALUE
|
1384
|
+
static VALUE
|
1385
|
+
line(VALUE self)
|
1116
1386
|
{
|
1117
1387
|
xmlNodePtr node;
|
1118
1388
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -1120,6 +1390,26 @@ static VALUE line(VALUE self)
|
|
1120
1390
|
return INT2NUM(xmlGetLineNo(node));
|
1121
1391
|
}
|
1122
1392
|
|
1393
|
+
/*
|
1394
|
+
* call-seq:
|
1395
|
+
* line=(num)
|
1396
|
+
*
|
1397
|
+
* Sets the line for this Node. num must be less than 65535.
|
1398
|
+
*/
|
1399
|
+
static VALUE
|
1400
|
+
set_line(VALUE self, VALUE num)
|
1401
|
+
{
|
1402
|
+
xmlNodePtr node;
|
1403
|
+
int value = NUM2INT(num);
|
1404
|
+
|
1405
|
+
Data_Get_Struct(self, xmlNode, node);
|
1406
|
+
if (value < 65535) {
|
1407
|
+
node->line = value;
|
1408
|
+
}
|
1409
|
+
|
1410
|
+
return num;
|
1411
|
+
}
|
1412
|
+
|
1123
1413
|
/*
|
1124
1414
|
* call-seq:
|
1125
1415
|
* add_namespace_definition(prefix, href)
|
@@ -1131,45 +1421,47 @@ static VALUE line(VALUE self)
|
|
1131
1421
|
* show up in #attributes, but they will be included as an xmlns attribute
|
1132
1422
|
* when the node is serialized to XML.
|
1133
1423
|
*/
|
1134
|
-
static VALUE
|
1424
|
+
static VALUE
|
1425
|
+
add_namespace_definition(VALUE rb_node, VALUE rb_prefix, VALUE rb_href)
|
1135
1426
|
{
|
1136
|
-
xmlNodePtr
|
1137
|
-
xmlNsPtr
|
1427
|
+
xmlNodePtr c_node, element;
|
1428
|
+
xmlNsPtr c_namespace;
|
1429
|
+
const xmlChar *c_prefix = (const xmlChar *)(NIL_P(rb_prefix) ? NULL : StringValueCStr(rb_prefix));
|
1138
1430
|
|
1139
|
-
Data_Get_Struct(
|
1140
|
-
|
1431
|
+
Data_Get_Struct(rb_node, xmlNode, c_node);
|
1432
|
+
element = c_node ;
|
1141
1433
|
|
1142
|
-
|
1143
|
-
node->doc,
|
1144
|
-
node,
|
1145
|
-
(const xmlChar *)(NIL_P(prefix) ? NULL : StringValuePtr(prefix))
|
1146
|
-
);
|
1434
|
+
c_namespace = xmlSearchNs(c_node->doc, c_node, c_prefix);
|
1147
1435
|
|
1148
|
-
if(!
|
1149
|
-
if (
|
1150
|
-
|
1436
|
+
if (!c_namespace) {
|
1437
|
+
if (c_node->type != XML_ELEMENT_NODE) {
|
1438
|
+
element = c_node->parent;
|
1151
1439
|
}
|
1152
|
-
|
1153
|
-
namespacee,
|
1154
|
-
(const xmlChar *)StringValuePtr(href),
|
1155
|
-
(const xmlChar *)(NIL_P(prefix) ? NULL : StringValuePtr(prefix))
|
1156
|
-
);
|
1440
|
+
c_namespace = xmlNewNs(element, (const xmlChar *)StringValueCStr(rb_href), c_prefix);
|
1157
1441
|
}
|
1158
1442
|
|
1159
|
-
if (!
|
1443
|
+
if (!c_namespace) {
|
1444
|
+
return Qnil ;
|
1445
|
+
}
|
1160
1446
|
|
1161
|
-
if(NIL_P(
|
1447
|
+
if (NIL_P(rb_prefix) || c_node != element) {
|
1448
|
+
xmlSetNs(c_node, c_namespace);
|
1449
|
+
}
|
1162
1450
|
|
1163
|
-
return
|
1451
|
+
return noko_xml_namespace_wrap(c_namespace, c_node->doc);
|
1164
1452
|
}
|
1165
1453
|
|
1166
1454
|
/*
|
1167
|
-
*
|
1168
|
-
* new
|
1169
|
-
*
|
1170
|
-
*
|
1455
|
+
* @overload new(name, document)
|
1456
|
+
* Create a new node with +name+ sharing GC lifecycle with +document+.
|
1457
|
+
* @param name [String]
|
1458
|
+
* @param document [Nokogiri::XML::Document]
|
1459
|
+
* @yieldparam node [Nokogiri::XML::Node]
|
1460
|
+
* @return [Nokogiri::XML::Node]
|
1461
|
+
* @see Nokogiri::XML::Node#initialize
|
1171
1462
|
*/
|
1172
|
-
static VALUE
|
1463
|
+
static VALUE
|
1464
|
+
rb_xml_node_new(int argc, VALUE *argv, VALUE klass)
|
1173
1465
|
{
|
1174
1466
|
xmlDocPtr doc;
|
1175
1467
|
xmlNodePtr node;
|
@@ -1182,17 +1474,17 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
|
|
1182
1474
|
|
1183
1475
|
Data_Get_Struct(document, xmlDoc, doc);
|
1184
1476
|
|
1185
|
-
node = xmlNewNode(NULL, (xmlChar *)
|
1477
|
+
node = xmlNewNode(NULL, (xmlChar *)StringValueCStr(name));
|
1186
1478
|
node->doc = doc->doc;
|
1187
|
-
|
1479
|
+
noko_xml_document_pin_node(node);
|
1188
1480
|
|
1189
|
-
rb_node =
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1481
|
+
rb_node = noko_xml_node_wrap(
|
1482
|
+
klass == cNokogiriXmlNode ? (VALUE)NULL : klass,
|
1483
|
+
node
|
1484
|
+
);
|
1193
1485
|
rb_obj_call_init(rb_node, argc, argv);
|
1194
1486
|
|
1195
|
-
if(rb_block_given_p()) rb_yield(rb_node);
|
1487
|
+
if (rb_block_given_p()) { rb_yield(rb_node); }
|
1196
1488
|
|
1197
1489
|
return rb_node;
|
1198
1490
|
}
|
@@ -1203,7 +1495,8 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
|
|
1203
1495
|
*
|
1204
1496
|
* Returns the Node as html.
|
1205
1497
|
*/
|
1206
|
-
static VALUE
|
1498
|
+
static VALUE
|
1499
|
+
dump_html(VALUE self)
|
1207
1500
|
{
|
1208
1501
|
xmlBufferPtr buf ;
|
1209
1502
|
xmlNodePtr node ;
|
@@ -1224,7 +1517,8 @@ static VALUE dump_html(VALUE self)
|
|
1224
1517
|
*
|
1225
1518
|
* Compare this Node to +other+ with respect to their Document
|
1226
1519
|
*/
|
1227
|
-
static VALUE
|
1520
|
+
static VALUE
|
1521
|
+
compare(VALUE self, VALUE _other)
|
1228
1522
|
{
|
1229
1523
|
xmlNodePtr node, other;
|
1230
1524
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -1241,7 +1535,8 @@ static VALUE compare(VALUE self, VALUE _other)
|
|
1241
1535
|
* Loads and substitutes all xinclude elements below the node. The
|
1242
1536
|
* parser context will be initialized with +options+.
|
1243
1537
|
*/
|
1244
|
-
static VALUE
|
1538
|
+
static VALUE
|
1539
|
+
process_xincludes(VALUE self, VALUE options)
|
1245
1540
|
{
|
1246
1541
|
int rcode ;
|
1247
1542
|
xmlNodePtr node;
|
@@ -1257,10 +1552,11 @@ static VALUE process_xincludes(VALUE self, VALUE options)
|
|
1257
1552
|
xmlErrorPtr error;
|
1258
1553
|
|
1259
1554
|
error = xmlGetLastError();
|
1260
|
-
if(error)
|
1261
|
-
rb_exc_raise(Nokogiri_wrap_xml_syntax_error(
|
1262
|
-
else
|
1555
|
+
if (error) {
|
1556
|
+
rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
|
1557
|
+
} else {
|
1263
1558
|
rb_raise(rb_eRuntimeError, "Could not perform xinclude substitution");
|
1559
|
+
}
|
1264
1560
|
}
|
1265
1561
|
|
1266
1562
|
return self;
|
@@ -1268,267 +1564,276 @@ static VALUE process_xincludes(VALUE self, VALUE options)
|
|
1268
1564
|
|
1269
1565
|
|
1270
1566
|
/* TODO: DOCUMENT ME */
|
1271
|
-
static VALUE
|
1567
|
+
static VALUE
|
1568
|
+
in_context(VALUE self, VALUE _str, VALUE _options)
|
1272
1569
|
{
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
1276
|
-
|
1277
|
-
|
1570
|
+
xmlNodePtr node, list = 0, tmp, child_iter, node_children, doc_children;
|
1571
|
+
xmlNodeSetPtr set;
|
1572
|
+
xmlParserErrors error;
|
1573
|
+
VALUE doc, err;
|
1574
|
+
int doc_is_empty;
|
1278
1575
|
|
1279
|
-
|
1576
|
+
Data_Get_Struct(self, xmlNode, node);
|
1280
1577
|
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1284
|
-
|
1285
|
-
|
1578
|
+
doc = DOC_RUBY_OBJECT(node->doc);
|
1579
|
+
err = rb_iv_get(doc, "@errors");
|
1580
|
+
doc_is_empty = (node->doc->children == NULL) ? 1 : 0;
|
1581
|
+
node_children = node->children;
|
1582
|
+
doc_children = node->doc->children;
|
1286
1583
|
|
1287
|
-
|
1584
|
+
xmlSetStructuredErrorFunc((void *)err, Nokogiri_error_array_pusher);
|
1288
1585
|
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1586
|
+
/* Twiddle global variable because of a bug in libxml2.
|
1587
|
+
* http://git.gnome.org/browse/libxml2/commit/?id=e20fb5a72c83cbfc8e4a8aa3943c6be8febadab7
|
1588
|
+
*/
|
1292
1589
|
#ifndef HTML_PARSE_NOIMPLIED
|
1293
|
-
|
1590
|
+
htmlHandleOmittedElem(0);
|
1294
1591
|
#endif
|
1295
1592
|
|
1296
|
-
|
1297
|
-
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
|
1593
|
+
/* This function adds a fake node to the child of +node+. If the parser
|
1594
|
+
* does not exit cleanly with XML_ERR_OK, the list is freed. This can
|
1595
|
+
* leave the child pointers in a bad state if they were originally empty.
|
1596
|
+
*
|
1597
|
+
* http://git.gnome.org/browse/libxml2/tree/parser.c#n13177
|
1598
|
+
* */
|
1599
|
+
error = xmlParseInNodeContext(node, StringValuePtr(_str),
|
1600
|
+
(int)RSTRING_LEN(_str),
|
1601
|
+
(int)NUM2INT(_options), &list);
|
1602
|
+
|
1603
|
+
/* xmlParseInNodeContext should not mutate the original document or node,
|
1604
|
+
* so reassigning these pointers should be OK. The reason we're reassigning
|
1605
|
+
* is because if there were errors, it's possible for the child pointers
|
1606
|
+
* to be manipulated. */
|
1607
|
+
if (error != XML_ERR_OK) {
|
1608
|
+
node->doc->children = doc_children;
|
1609
|
+
node->children = node_children;
|
1610
|
+
}
|
1314
1611
|
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1322
|
-
child_iter = child_iter->next;
|
1612
|
+
/* make sure parent/child pointers are coherent so an unlink will work
|
1613
|
+
* properly (#331)
|
1614
|
+
*/
|
1615
|
+
child_iter = node->doc->children ;
|
1616
|
+
while (child_iter) {
|
1617
|
+
if (child_iter->parent != (xmlNodePtr)node->doc) {
|
1618
|
+
child_iter->parent = (xmlNodePtr)node->doc;
|
1323
1619
|
}
|
1620
|
+
child_iter = child_iter->next;
|
1621
|
+
}
|
1324
1622
|
|
1325
1623
|
#ifndef HTML_PARSE_NOIMPLIED
|
1326
|
-
|
1624
|
+
htmlHandleOmittedElem(1);
|
1327
1625
|
#endif
|
1328
1626
|
|
1329
|
-
|
1330
|
-
|
1331
|
-
/* Workaround for a libxml2 bug where a parsing error may leave a broken
|
1332
|
-
* node reference in node->doc->children.
|
1333
|
-
* This workaround is limited to when a parse error occurs, the document
|
1334
|
-
* went from having no children to having children, and the context node is
|
1335
|
-
* part of a document fragment.
|
1336
|
-
* https://bugzilla.gnome.org/show_bug.cgi?id=668155
|
1337
|
-
*/
|
1338
|
-
if (error != XML_ERR_OK && doc_is_empty && node->doc->children != NULL) {
|
1339
|
-
child_iter = node;
|
1340
|
-
while (child_iter->parent)
|
1341
|
-
child_iter = child_iter->parent;
|
1627
|
+
xmlSetStructuredErrorFunc(NULL, NULL);
|
1342
1628
|
|
1343
|
-
|
1344
|
-
|
1629
|
+
/* Workaround for a libxml2 bug where a parsing error may leave a broken
|
1630
|
+
* node reference in node->doc->children.
|
1631
|
+
* This workaround is limited to when a parse error occurs, the document
|
1632
|
+
* went from having no children to having children, and the context node is
|
1633
|
+
* part of a document fragment.
|
1634
|
+
* https://bugzilla.gnome.org/show_bug.cgi?id=668155
|
1635
|
+
*/
|
1636
|
+
if (error != XML_ERR_OK && doc_is_empty && node->doc->children != NULL) {
|
1637
|
+
child_iter = node;
|
1638
|
+
while (child_iter->parent) {
|
1639
|
+
child_iter = child_iter->parent;
|
1345
1640
|
}
|
1346
1641
|
|
1347
|
-
|
1348
|
-
|
1349
|
-
case XML_ERR_INTERNAL_ERROR:
|
1350
|
-
case XML_ERR_NO_MEMORY:
|
1351
|
-
rb_raise(rb_eRuntimeError, "error parsing fragment (%d)", error);
|
1352
|
-
break;
|
1353
|
-
default:
|
1354
|
-
break;
|
1642
|
+
if (child_iter->type == XML_DOCUMENT_FRAG_NODE) {
|
1643
|
+
node->doc->children = NULL;
|
1355
1644
|
}
|
1645
|
+
}
|
1356
1646
|
|
1357
|
-
|
1647
|
+
/* FIXME: This probably needs to handle more constants... */
|
1648
|
+
switch (error) {
|
1649
|
+
case XML_ERR_INTERNAL_ERROR:
|
1650
|
+
case XML_ERR_NO_MEMORY:
|
1651
|
+
rb_raise(rb_eRuntimeError, "error parsing fragment (%d)", error);
|
1652
|
+
break;
|
1653
|
+
default:
|
1654
|
+
break;
|
1655
|
+
}
|
1358
1656
|
|
1359
|
-
|
1360
|
-
tmp = list->next;
|
1361
|
-
list->next = NULL;
|
1362
|
-
xmlXPathNodeSetAddUnique(set, list);
|
1363
|
-
nokogiri_root_node(list);
|
1364
|
-
list = tmp;
|
1365
|
-
}
|
1657
|
+
set = xmlXPathNodeSetCreate(NULL);
|
1366
1658
|
|
1367
|
-
|
1659
|
+
while (list) {
|
1660
|
+
tmp = list->next;
|
1661
|
+
list->next = NULL;
|
1662
|
+
xmlXPathNodeSetAddUnique(set, list);
|
1663
|
+
noko_xml_document_pin_node(list);
|
1664
|
+
list = tmp;
|
1665
|
+
}
|
1666
|
+
|
1667
|
+
return noko_xml_node_set_wrap(set, doc);
|
1368
1668
|
}
|
1369
1669
|
|
1370
1670
|
|
1371
|
-
VALUE
|
1671
|
+
VALUE
|
1672
|
+
noko_xml_node_wrap(VALUE rb_class, xmlNodePtr c_node)
|
1372
1673
|
{
|
1373
|
-
VALUE
|
1374
|
-
VALUE node_cache = Qnil ;
|
1375
|
-
VALUE rb_node = Qnil ;
|
1674
|
+
VALUE rb_document, rb_node_cache, rb_node;
|
1376
1675
|
nokogiriTuplePtr node_has_a_document;
|
1377
|
-
xmlDocPtr
|
1676
|
+
xmlDocPtr c_doc;
|
1378
1677
|
void (*mark_method)(xmlNodePtr) = NULL ;
|
1379
1678
|
|
1380
|
-
assert(
|
1679
|
+
assert(c_node);
|
1381
1680
|
|
1382
|
-
if(
|
1383
|
-
|
1681
|
+
if (c_node->type == XML_DOCUMENT_NODE || c_node->type == XML_HTML_DOCUMENT_NODE) {
|
1682
|
+
return DOC_RUBY_OBJECT(c_node->doc);
|
1683
|
+
}
|
1384
1684
|
|
1385
1685
|
/* It's OK if the node doesn't have a fully-realized document (as in XML::Reader). */
|
1386
1686
|
/* see https://github.com/sparklemotion/nokogiri/issues/95 */
|
1387
1687
|
/* and https://github.com/sparklemotion/nokogiri/issues/439 */
|
1388
|
-
|
1389
|
-
if (
|
1390
|
-
node_has_a_document = DOC_RUBY_OBJECT_TEST(
|
1688
|
+
c_doc = c_node->doc;
|
1689
|
+
if (c_doc->type == XML_DOCUMENT_FRAG_NODE) { c_doc = c_doc->doc; }
|
1690
|
+
node_has_a_document = DOC_RUBY_OBJECT_TEST(c_doc);
|
1391
1691
|
|
1392
|
-
if(
|
1393
|
-
return (VALUE)
|
1692
|
+
if (c_node->_private && node_has_a_document) {
|
1693
|
+
return (VALUE)c_node->_private;
|
1694
|
+
}
|
1394
1695
|
|
1395
|
-
if(!RTEST(
|
1396
|
-
switch(
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1435
|
-
klass = cNokogiriXmlNode;
|
1696
|
+
if (!RTEST(rb_class)) {
|
1697
|
+
switch (c_node->type) {
|
1698
|
+
case XML_ELEMENT_NODE:
|
1699
|
+
rb_class = cNokogiriXmlElement;
|
1700
|
+
break;
|
1701
|
+
case XML_TEXT_NODE:
|
1702
|
+
rb_class = cNokogiriXmlText;
|
1703
|
+
break;
|
1704
|
+
case XML_ATTRIBUTE_NODE:
|
1705
|
+
rb_class = cNokogiriXmlAttr;
|
1706
|
+
break;
|
1707
|
+
case XML_ENTITY_REF_NODE:
|
1708
|
+
rb_class = cNokogiriXmlEntityReference;
|
1709
|
+
break;
|
1710
|
+
case XML_COMMENT_NODE:
|
1711
|
+
rb_class = cNokogiriXmlComment;
|
1712
|
+
break;
|
1713
|
+
case XML_DOCUMENT_FRAG_NODE:
|
1714
|
+
rb_class = cNokogiriXmlDocumentFragment;
|
1715
|
+
break;
|
1716
|
+
case XML_PI_NODE:
|
1717
|
+
rb_class = cNokogiriXmlProcessingInstruction;
|
1718
|
+
break;
|
1719
|
+
case XML_ENTITY_DECL:
|
1720
|
+
rb_class = cNokogiriXmlEntityDecl;
|
1721
|
+
break;
|
1722
|
+
case XML_CDATA_SECTION_NODE:
|
1723
|
+
rb_class = cNokogiriXmlCData;
|
1724
|
+
break;
|
1725
|
+
case XML_DTD_NODE:
|
1726
|
+
rb_class = cNokogiriXmlDtd;
|
1727
|
+
break;
|
1728
|
+
case XML_ATTRIBUTE_DECL:
|
1729
|
+
rb_class = cNokogiriXmlAttributeDecl;
|
1730
|
+
break;
|
1731
|
+
case XML_ELEMENT_DECL:
|
1732
|
+
rb_class = cNokogiriXmlElementDecl;
|
1733
|
+
break;
|
1734
|
+
default:
|
1735
|
+
rb_class = cNokogiriXmlNode;
|
1436
1736
|
}
|
1437
1737
|
}
|
1438
1738
|
|
1439
1739
|
mark_method = node_has_a_document ? mark : NULL ;
|
1440
1740
|
|
1441
|
-
rb_node = Data_Wrap_Struct(
|
1442
|
-
|
1741
|
+
rb_node = Data_Wrap_Struct(rb_class, mark_method, debug_node_dealloc, c_node) ;
|
1742
|
+
c_node->_private = (void *)rb_node;
|
1443
1743
|
|
1444
1744
|
if (node_has_a_document) {
|
1445
|
-
|
1446
|
-
|
1447
|
-
rb_ary_push(
|
1448
|
-
rb_funcall(
|
1745
|
+
rb_document = DOC_RUBY_OBJECT(c_doc);
|
1746
|
+
rb_node_cache = DOC_NODE_CACHE(c_doc);
|
1747
|
+
rb_ary_push(rb_node_cache, rb_node);
|
1748
|
+
rb_funcall(rb_document, id_decorate, 1, rb_node);
|
1449
1749
|
}
|
1450
1750
|
|
1451
1751
|
return rb_node ;
|
1452
1752
|
}
|
1453
1753
|
|
1454
1754
|
|
1455
|
-
|
1755
|
+
/*
|
1756
|
+
* return Array<Nokogiri::XML::Attr> containing the node's attributes
|
1757
|
+
*/
|
1758
|
+
VALUE
|
1759
|
+
noko_xml_node_attrs(xmlNodePtr c_node)
|
1456
1760
|
{
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1761
|
+
VALUE rb_properties = rb_ary_new();
|
1762
|
+
xmlAttrPtr c_property;
|
1763
|
+
|
1764
|
+
c_property = c_node->properties ;
|
1765
|
+
while (c_property != NULL) {
|
1766
|
+
rb_ary_push(rb_properties, noko_xml_node_wrap(Qnil, (xmlNodePtr)c_property));
|
1767
|
+
c_property = c_property->next ;
|
1462
1768
|
}
|
1463
|
-
}
|
1464
1769
|
|
1465
|
-
|
1466
|
-
|
1770
|
+
return rb_properties;
|
1771
|
+
}
|
1467
1772
|
|
1468
|
-
void
|
1773
|
+
void
|
1774
|
+
noko_init_xml_node()
|
1469
1775
|
{
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
cNokogiriXmlNode
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
rb_define_method(
|
1481
|
-
rb_define_method(
|
1482
|
-
rb_define_method(
|
1483
|
-
rb_define_method(
|
1484
|
-
rb_define_method(
|
1485
|
-
rb_define_method(
|
1486
|
-
rb_define_method(
|
1487
|
-
rb_define_method(
|
1488
|
-
rb_define_method(
|
1489
|
-
rb_define_method(
|
1490
|
-
rb_define_method(
|
1491
|
-
rb_define_method(
|
1492
|
-
rb_define_method(
|
1493
|
-
rb_define_method(
|
1494
|
-
rb_define_method(
|
1495
|
-
rb_define_method(
|
1496
|
-
rb_define_method(
|
1497
|
-
rb_define_method(
|
1498
|
-
rb_define_method(
|
1499
|
-
rb_define_method(
|
1500
|
-
rb_define_method(
|
1501
|
-
rb_define_method(
|
1502
|
-
rb_define_method(
|
1503
|
-
rb_define_method(
|
1504
|
-
rb_define_method(
|
1505
|
-
rb_define_method(
|
1506
|
-
rb_define_method(
|
1507
|
-
rb_define_method(
|
1508
|
-
rb_define_method(
|
1509
|
-
rb_define_method(
|
1510
|
-
rb_define_method(
|
1511
|
-
rb_define_method(
|
1512
|
-
rb_define_method(
|
1513
|
-
rb_define_method(
|
1514
|
-
rb_define_method(
|
1515
|
-
|
1516
|
-
|
1517
|
-
rb_define_private_method(
|
1518
|
-
rb_define_private_method(
|
1519
|
-
rb_define_private_method(
|
1520
|
-
rb_define_private_method(
|
1521
|
-
rb_define_private_method(
|
1522
|
-
rb_define_private_method(
|
1523
|
-
rb_define_private_method(
|
1524
|
-
rb_define_private_method(
|
1525
|
-
rb_define_private_method(
|
1526
|
-
rb_define_private_method(
|
1527
|
-
rb_define_private_method(
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
decorate_bang = rb_intern("decorate!");
|
1776
|
+
cNokogiriXmlNode = rb_define_class_under(mNokogiriXml, "Node", rb_cObject);
|
1777
|
+
|
1778
|
+
rb_undef_alloc_func(cNokogiriXmlNode);
|
1779
|
+
|
1780
|
+
rb_define_singleton_method(cNokogiriXmlNode, "new", rb_xml_node_new, -1);
|
1781
|
+
|
1782
|
+
rb_define_method(cNokogiriXmlNode, "add_namespace_definition", add_namespace_definition, 2);
|
1783
|
+
rb_define_method(cNokogiriXmlNode, "node_name", get_name, 0);
|
1784
|
+
rb_define_method(cNokogiriXmlNode, "document", document, 0);
|
1785
|
+
rb_define_method(cNokogiriXmlNode, "node_name=", set_name, 1);
|
1786
|
+
rb_define_method(cNokogiriXmlNode, "parent", get_parent, 0);
|
1787
|
+
rb_define_method(cNokogiriXmlNode, "child", child, 0);
|
1788
|
+
rb_define_method(cNokogiriXmlNode, "first_element_child", first_element_child, 0);
|
1789
|
+
rb_define_method(cNokogiriXmlNode, "last_element_child", last_element_child, 0);
|
1790
|
+
rb_define_method(cNokogiriXmlNode, "children", children, 0);
|
1791
|
+
rb_define_method(cNokogiriXmlNode, "element_children", element_children, 0);
|
1792
|
+
rb_define_method(cNokogiriXmlNode, "next_sibling", next_sibling, 0);
|
1793
|
+
rb_define_method(cNokogiriXmlNode, "previous_sibling", previous_sibling, 0);
|
1794
|
+
rb_define_method(cNokogiriXmlNode, "next_element", next_element, 0);
|
1795
|
+
rb_define_method(cNokogiriXmlNode, "previous_element", previous_element, 0);
|
1796
|
+
rb_define_method(cNokogiriXmlNode, "node_type", node_type, 0);
|
1797
|
+
rb_define_method(cNokogiriXmlNode, "path", noko_xml_node_path, 0);
|
1798
|
+
rb_define_method(cNokogiriXmlNode, "key?", key_eh, 1);
|
1799
|
+
rb_define_method(cNokogiriXmlNode, "namespaced_key?", namespaced_key_eh, 2);
|
1800
|
+
rb_define_method(cNokogiriXmlNode, "blank?", blank_eh, 0);
|
1801
|
+
rb_define_method(cNokogiriXmlNode, "attribute_nodes", attribute_nodes, 0);
|
1802
|
+
rb_define_method(cNokogiriXmlNode, "attribute", attr, 1);
|
1803
|
+
rb_define_method(cNokogiriXmlNode, "attribute_with_ns", attribute_with_ns, 2);
|
1804
|
+
rb_define_method(cNokogiriXmlNode, "namespace", noko_xml_node_namespace, 0);
|
1805
|
+
rb_define_method(cNokogiriXmlNode, "namespace_definitions", namespace_definitions, 0);
|
1806
|
+
rb_define_method(cNokogiriXmlNode, "namespace_scopes", namespace_scopes, 0);
|
1807
|
+
rb_define_method(cNokogiriXmlNode, "encode_special_chars", encode_special_chars, 1);
|
1808
|
+
rb_define_method(cNokogiriXmlNode, "dup", duplicate_node, -1);
|
1809
|
+
rb_define_method(cNokogiriXmlNode, "unlink", unlink_node, 0);
|
1810
|
+
rb_define_method(cNokogiriXmlNode, "internal_subset", internal_subset, 0);
|
1811
|
+
rb_define_method(cNokogiriXmlNode, "external_subset", external_subset, 0);
|
1812
|
+
rb_define_method(cNokogiriXmlNode, "create_internal_subset", create_internal_subset, 3);
|
1813
|
+
rb_define_method(cNokogiriXmlNode, "create_external_subset", create_external_subset, 3);
|
1814
|
+
rb_define_method(cNokogiriXmlNode, "pointer_id", pointer_id, 0);
|
1815
|
+
rb_define_method(cNokogiriXmlNode, "line", line, 0);
|
1816
|
+
rb_define_method(cNokogiriXmlNode, "line=", set_line, 1);
|
1817
|
+
rb_define_method(cNokogiriXmlNode, "content", get_native_content, 0);
|
1818
|
+
rb_define_method(cNokogiriXmlNode, "native_content=", set_native_content, 1);
|
1819
|
+
rb_define_method(cNokogiriXmlNode, "lang", get_lang, 0);
|
1820
|
+
rb_define_method(cNokogiriXmlNode, "lang=", set_lang, 1);
|
1821
|
+
|
1822
|
+
rb_define_private_method(cNokogiriXmlNode, "process_xincludes", process_xincludes, 1);
|
1823
|
+
rb_define_private_method(cNokogiriXmlNode, "in_context", in_context, 2);
|
1824
|
+
rb_define_private_method(cNokogiriXmlNode, "add_child_node", add_child, 1);
|
1825
|
+
rb_define_private_method(cNokogiriXmlNode, "add_previous_sibling_node", add_previous_sibling, 1);
|
1826
|
+
rb_define_private_method(cNokogiriXmlNode, "add_next_sibling_node", add_next_sibling, 1);
|
1827
|
+
rb_define_private_method(cNokogiriXmlNode, "replace_node", replace, 1);
|
1828
|
+
rb_define_private_method(cNokogiriXmlNode, "dump_html", dump_html, 0);
|
1829
|
+
rb_define_private_method(cNokogiriXmlNode, "native_write_to", native_write_to, 4);
|
1830
|
+
rb_define_private_method(cNokogiriXmlNode, "get", get, 1);
|
1831
|
+
rb_define_private_method(cNokogiriXmlNode, "set", set, 2);
|
1832
|
+
rb_define_private_method(cNokogiriXmlNode, "set_namespace", set_namespace, 1);
|
1833
|
+
rb_define_private_method(cNokogiriXmlNode, "compare", compare, 1);
|
1834
|
+
|
1835
|
+
id_decorate = rb_intern("decorate");
|
1836
|
+
id_decorate_bang = rb_intern("decorate!");
|
1532
1837
|
}
|
1533
1838
|
|
1534
1839
|
/* vim: set noet sw=4 sws=4 */
|