nokogiri 1.11.1 → 1.12.0.rc1
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 +4 -4
- data/LICENSE-DEPENDENCIES.md +232 -11
- data/LICENSE.md +1 -1
- data/README.md +27 -21
- data/dependencies.yml +12 -12
- data/ext/nokogiri/depend +35 -474
- data/ext/nokogiri/extconf.rb +391 -243
- data/ext/nokogiri/gumbo.c +611 -0
- data/ext/nokogiri/{html_document.c → html4_document.c} +18 -23
- 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 +119 -0
- data/ext/nokogiri/{html_sax_push_parser.c → html4_sax_push_parser.c} +29 -27
- data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
- data/ext/nokogiri/nokogiri.c +206 -66
- data/ext/nokogiri/nokogiri.h +166 -76
- data/ext/nokogiri/test_global_handlers.c +3 -4
- data/ext/nokogiri/xml_attr.c +15 -15
- data/ext/nokogiri/xml_attribute_decl.c +18 -18
- data/ext/nokogiri/xml_cdata.c +13 -18
- data/ext/nokogiri/xml_comment.c +19 -26
- data/ext/nokogiri/xml_document.c +258 -200
- 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 +28 -17
- data/ext/nokogiri/xml_entity_decl.c +32 -30
- data/ext/nokogiri/xml_entity_reference.c +16 -18
- data/ext/nokogiri/xml_namespace.c +58 -49
- data/ext/nokogiri/xml_node.c +473 -414
- data/ext/nokogiri/xml_node_set.c +174 -162
- data/ext/nokogiri/xml_processing_instruction.c +17 -19
- data/ext/nokogiri/xml_reader.c +193 -157
- data/ext/nokogiri/xml_relax_ng.c +29 -23
- data/ext/nokogiri/xml_sax_parser.c +111 -106
- data/ext/nokogiri/xml_sax_parser_context.c +102 -85
- data/ext/nokogiri/xml_sax_push_parser.c +34 -27
- data/ext/nokogiri/xml_schema.c +49 -41
- data/ext/nokogiri/xml_syntax_error.c +21 -23
- data/ext/nokogiri/xml_text.c +13 -17
- data/ext/nokogiri/xml_xpath_context.c +86 -77
- data/ext/nokogiri/xslt_stylesheet.c +157 -156
- data/gumbo-parser/CHANGES.md +63 -0
- data/gumbo-parser/Makefile +101 -0
- data/gumbo-parser/THANKS +27 -0
- data/gumbo-parser/src/Makefile +17 -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.rb +31 -50
- data/lib/nokogiri/css.rb +14 -14
- data/lib/nokogiri/css/parser.rb +2 -2
- data/lib/nokogiri/css/parser.y +1 -1
- data/lib/nokogiri/css/syntax_error.rb +1 -1
- data/lib/nokogiri/extension.rb +26 -0
- data/lib/nokogiri/gumbo.rb +14 -0
- data/lib/nokogiri/html.rb +31 -27
- data/lib/nokogiri/html4.rb +40 -0
- data/lib/nokogiri/{html → html4}/builder.rb +2 -2
- data/lib/nokogiri/{html → html4}/document.rb +4 -4
- data/lib/nokogiri/{html → html4}/document_fragment.rb +17 -17
- data/lib/nokogiri/{html → html4}/element_description.rb +1 -1
- data/lib/nokogiri/{html → html4}/element_description_defaults.rb +1 -1
- data/lib/nokogiri/{html → html4}/entity_lookup.rb +1 -1
- data/lib/nokogiri/{html → html4}/sax/parser.rb +11 -14
- data/lib/nokogiri/html4/sax/parser_context.rb +19 -0
- data/lib/nokogiri/{html → html4}/sax/push_parser.rb +5 -5
- data/lib/nokogiri/html5.rb +473 -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/version/constant.rb +1 -1
- data/lib/nokogiri/version/info.rb +42 -9
- data/lib/nokogiri/xml.rb +35 -36
- data/lib/nokogiri/xml/document.rb +74 -28
- data/lib/nokogiri/xml/node.rb +45 -47
- data/lib/nokogiri/xml/parse_options.rb +2 -0
- data/lib/nokogiri/xml/pp.rb +2 -2
- data/lib/nokogiri/xml/reader.rb +2 -9
- data/lib/nokogiri/xml/sax.rb +4 -4
- data/lib/nokogiri/xml/sax/document.rb +24 -30
- data/lib/nokogiri/xml/xpath.rb +3 -5
- data/lib/nokogiri/xml/xpath/syntax_error.rb +1 -1
- data/lib/nokogiri/xslt.rb +16 -16
- data/lib/nokogiri/xslt/stylesheet.rb +1 -1
- data/patches/libxml2/{0002-Remove-script-macro-support.patch → 0001-Remove-script-macro-support.patch} +0 -0
- data/patches/libxml2/{0003-Update-entities-to-remove-handling-of-ssi.patch → 0002-Update-entities-to-remove-handling-of-ssi.patch} +0 -0
- data/patches/libxml2/{0004-libxml2.la-is-in-top_builddir.patch → 0003-libxml2.la-is-in-top_builddir.patch} +1 -1
- data/patches/libxml2/{0008-use-glibc-strlen.patch → 0004-use-glibc-strlen.patch} +0 -0
- data/patches/libxml2/{0009-avoid-isnan-isinf.patch → 0005-avoid-isnan-isinf.patch} +4 -4
- 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
- metadata +117 -109
- 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 -118
- data/ext/nokogiri/html_sax_parser_context.h +0 -11
- 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 -63
- 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 -14
- data/ext/nokogiri/xml_node.h +0 -13
- data/ext/nokogiri/xml_node_set.h +0 -12
- 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 -25
- 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 -17
- data/patches/libxml2/0001-Revert-Do-not-URI-escape-in-server-side-includes.patch +0 -78
- data/patches/libxml2/0005-Fix-infinite-loop-in-xmlStringLenDecodeEntities.patch +0 -32
- data/patches/libxml2/0006-htmlParseComment-treat-as-if-it-closed-the-comment.patch +0 -73
- data/patches/libxml2/0007-use-new-htmlParseLookupCommentEnd-to-find-comment-en.patch +0 -103
- data/ports/archives/libxml2-2.9.10.tar.gz +0 -0
@@ -1,17 +1,22 @@
|
|
1
|
-
#include <
|
1
|
+
#include <nokogiri.h>
|
2
|
+
|
3
|
+
VALUE cNokogiriEncodingHandler;
|
4
|
+
|
2
5
|
|
3
6
|
/*
|
4
7
|
* call-seq: Nokogiri::EncodingHandler.[](name)
|
5
8
|
*
|
6
9
|
* Get the encoding handler for +name+
|
7
10
|
*/
|
8
|
-
static VALUE
|
11
|
+
static VALUE
|
12
|
+
get(VALUE klass, VALUE key)
|
9
13
|
{
|
10
14
|
xmlCharEncodingHandlerPtr handler;
|
11
15
|
|
12
16
|
handler = xmlFindCharEncodingHandler(StringValueCStr(key));
|
13
|
-
if(handler)
|
17
|
+
if (handler) {
|
14
18
|
return Data_Wrap_Struct(klass, NULL, NULL, handler);
|
19
|
+
}
|
15
20
|
|
16
21
|
return Qnil;
|
17
22
|
}
|
@@ -21,9 +26,10 @@ static VALUE get(VALUE klass, VALUE key)
|
|
21
26
|
*
|
22
27
|
* Delete the encoding alias named +name+
|
23
28
|
*/
|
24
|
-
static VALUE
|
29
|
+
static VALUE
|
30
|
+
delete (VALUE klass, VALUE name)
|
25
31
|
{
|
26
|
-
if(xmlDelEncodingAlias(StringValueCStr(name))) return Qnil;
|
32
|
+
if (xmlDelEncodingAlias(StringValueCStr(name))) { return Qnil; }
|
27
33
|
|
28
34
|
return Qtrue;
|
29
35
|
}
|
@@ -33,7 +39,8 @@ static VALUE delete(VALUE klass, VALUE name)
|
|
33
39
|
*
|
34
40
|
* Alias encoding handler with name +from+ to name +to+
|
35
41
|
*/
|
36
|
-
static VALUE
|
42
|
+
static VALUE
|
43
|
+
alias(VALUE klass, VALUE from, VALUE to)
|
37
44
|
{
|
38
45
|
xmlAddEncodingAlias(StringValueCStr(from), StringValueCStr(to));
|
39
46
|
|
@@ -45,7 +52,8 @@ static VALUE alias(VALUE klass, VALUE from, VALUE to)
|
|
45
52
|
*
|
46
53
|
* Remove all encoding aliases.
|
47
54
|
*/
|
48
|
-
static VALUE
|
55
|
+
static VALUE
|
56
|
+
clear_aliases(VALUE klass)
|
49
57
|
{
|
50
58
|
xmlCleanupEncodingAliases();
|
51
59
|
|
@@ -57,7 +65,8 @@ static VALUE clear_aliases(VALUE klass)
|
|
57
65
|
*
|
58
66
|
* Get the name of this EncodingHandler
|
59
67
|
*/
|
60
|
-
static VALUE
|
68
|
+
static VALUE
|
69
|
+
name(VALUE self)
|
61
70
|
{
|
62
71
|
xmlCharEncodingHandlerPtr handler;
|
63
72
|
|
@@ -66,14 +75,16 @@ static VALUE name(VALUE self)
|
|
66
75
|
return NOKOGIRI_STR_NEW2(handler->name);
|
67
76
|
}
|
68
77
|
|
69
|
-
void
|
78
|
+
void
|
79
|
+
noko_init_xml_encoding_handler()
|
70
80
|
{
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
rb_define_singleton_method(
|
76
|
-
rb_define_singleton_method(
|
77
|
-
rb_define_singleton_method(
|
78
|
-
|
81
|
+
cNokogiriEncodingHandler = rb_define_class_under(mNokogiri, "EncodingHandler", rb_cObject);
|
82
|
+
|
83
|
+
rb_undef_alloc_func(cNokogiriEncodingHandler);
|
84
|
+
|
85
|
+
rb_define_singleton_method(cNokogiriEncodingHandler, "[]", get, 1);
|
86
|
+
rb_define_singleton_method(cNokogiriEncodingHandler, "delete", delete, 1);
|
87
|
+
rb_define_singleton_method(cNokogiriEncodingHandler, "alias", alias, 2);
|
88
|
+
rb_define_singleton_method(cNokogiriEncodingHandler, "clear_aliases!", clear_aliases, 0);
|
89
|
+
rb_define_method(cNokogiriEncodingHandler, "name", name, 0);
|
79
90
|
}
|
@@ -1,4 +1,6 @@
|
|
1
|
-
#include <
|
1
|
+
#include <nokogiri.h>
|
2
|
+
|
3
|
+
VALUE cNokogiriXmlEntityDecl;
|
2
4
|
|
3
5
|
/*
|
4
6
|
* call-seq:
|
@@ -6,12 +8,13 @@
|
|
6
8
|
*
|
7
9
|
* Get the original_content before ref substitution
|
8
10
|
*/
|
9
|
-
static VALUE
|
11
|
+
static VALUE
|
12
|
+
original_content(VALUE self)
|
10
13
|
{
|
11
14
|
xmlEntityPtr node;
|
12
15
|
Data_Get_Struct(self, xmlEntity, node);
|
13
16
|
|
14
|
-
if(!node->orig) return Qnil;
|
17
|
+
if (!node->orig) { return Qnil; }
|
15
18
|
|
16
19
|
return NOKOGIRI_STR_NEW2(node->orig);
|
17
20
|
}
|
@@ -22,12 +25,13 @@ static VALUE original_content(VALUE self)
|
|
22
25
|
*
|
23
26
|
* Get the content
|
24
27
|
*/
|
25
|
-
static VALUE
|
28
|
+
static VALUE
|
29
|
+
get_content(VALUE self)
|
26
30
|
{
|
27
31
|
xmlEntityPtr node;
|
28
32
|
Data_Get_Struct(self, xmlEntity, node);
|
29
33
|
|
30
|
-
if(!node->content) return Qnil;
|
34
|
+
if (!node->content) { return Qnil; }
|
31
35
|
|
32
36
|
return NOKOGIRI_STR_NEW(node->content, node->length);
|
33
37
|
}
|
@@ -38,7 +42,8 @@ static VALUE get_content(VALUE self)
|
|
38
42
|
*
|
39
43
|
* Get the entity type
|
40
44
|
*/
|
41
|
-
static VALUE
|
45
|
+
static VALUE
|
46
|
+
entity_type(VALUE self)
|
42
47
|
{
|
43
48
|
xmlEntityPtr node;
|
44
49
|
Data_Get_Struct(self, xmlEntity, node);
|
@@ -52,12 +57,13 @@ static VALUE entity_type(VALUE self)
|
|
52
57
|
*
|
53
58
|
* Get the external identifier for PUBLIC
|
54
59
|
*/
|
55
|
-
static VALUE
|
60
|
+
static VALUE
|
61
|
+
external_id(VALUE self)
|
56
62
|
{
|
57
63
|
xmlEntityPtr node;
|
58
64
|
Data_Get_Struct(self, xmlEntity, node);
|
59
65
|
|
60
|
-
if(!node->ExternalID) return Qnil;
|
66
|
+
if (!node->ExternalID) { return Qnil; }
|
61
67
|
|
62
68
|
return NOKOGIRI_STR_NEW2(node->ExternalID);
|
63
69
|
}
|
@@ -68,43 +74,39 @@ static VALUE external_id(VALUE self)
|
|
68
74
|
*
|
69
75
|
* Get the URI for a SYSTEM or PUBLIC Entity
|
70
76
|
*/
|
71
|
-
static VALUE
|
77
|
+
static VALUE
|
78
|
+
system_id(VALUE self)
|
72
79
|
{
|
73
80
|
xmlEntityPtr node;
|
74
81
|
Data_Get_Struct(self, xmlEntity, node);
|
75
82
|
|
76
|
-
if(!node->SystemID) return Qnil;
|
83
|
+
if (!node->SystemID) { return Qnil; }
|
77
84
|
|
78
85
|
return NOKOGIRI_STR_NEW2(node->SystemID);
|
79
86
|
}
|
80
87
|
|
81
|
-
|
82
|
-
|
83
|
-
void init_xml_entity_decl()
|
88
|
+
void
|
89
|
+
noko_init_xml_entity_decl()
|
84
90
|
{
|
85
|
-
|
86
|
-
|
87
|
-
VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
|
88
|
-
VALUE klass = rb_define_class_under(xml, "EntityDecl", node);
|
89
|
-
|
90
|
-
cNokogiriXmlEntityDecl = klass;
|
91
|
+
assert(cNokogiriXmlNode);
|
92
|
+
cNokogiriXmlEntityDecl = rb_define_class_under(mNokogiriXml, "EntityDecl", cNokogiriXmlNode);
|
91
93
|
|
92
|
-
rb_define_method(
|
93
|
-
rb_define_method(
|
94
|
-
rb_define_method(
|
95
|
-
rb_define_method(
|
96
|
-
rb_define_method(
|
94
|
+
rb_define_method(cNokogiriXmlEntityDecl, "original_content", original_content, 0);
|
95
|
+
rb_define_method(cNokogiriXmlEntityDecl, "content", get_content, 0);
|
96
|
+
rb_define_method(cNokogiriXmlEntityDecl, "entity_type", entity_type, 0);
|
97
|
+
rb_define_method(cNokogiriXmlEntityDecl, "external_id", external_id, 0);
|
98
|
+
rb_define_method(cNokogiriXmlEntityDecl, "system_id", system_id, 0);
|
97
99
|
|
98
100
|
rb_const_set(cNokogiriXmlEntityDecl, rb_intern("INTERNAL_GENERAL"),
|
99
|
-
|
101
|
+
INT2NUM(XML_INTERNAL_GENERAL_ENTITY));
|
100
102
|
rb_const_set(cNokogiriXmlEntityDecl, rb_intern("EXTERNAL_GENERAL_PARSED"),
|
101
|
-
|
103
|
+
INT2NUM(XML_EXTERNAL_GENERAL_PARSED_ENTITY));
|
102
104
|
rb_const_set(cNokogiriXmlEntityDecl, rb_intern("EXTERNAL_GENERAL_UNPARSED"),
|
103
|
-
|
105
|
+
INT2NUM(XML_EXTERNAL_GENERAL_UNPARSED_ENTITY));
|
104
106
|
rb_const_set(cNokogiriXmlEntityDecl, rb_intern("INTERNAL_PARAMETER"),
|
105
|
-
|
107
|
+
INT2NUM(XML_INTERNAL_PARAMETER_ENTITY));
|
106
108
|
rb_const_set(cNokogiriXmlEntityDecl, rb_intern("EXTERNAL_PARAMETER"),
|
107
|
-
|
109
|
+
INT2NUM(XML_EXTERNAL_PARAMETER_ENTITY));
|
108
110
|
rb_const_set(cNokogiriXmlEntityDecl, rb_intern("INTERNAL_PREDEFINED"),
|
109
|
-
|
111
|
+
INT2NUM(XML_INTERNAL_PREDEFINED_ENTITY));
|
110
112
|
}
|
@@ -1,4 +1,6 @@
|
|
1
|
-
#include <
|
1
|
+
#include <nokogiri.h>
|
2
|
+
|
3
|
+
VALUE cNokogiriXmlEntityReference;
|
2
4
|
|
3
5
|
/*
|
4
6
|
* call-seq:
|
@@ -6,7 +8,8 @@
|
|
6
8
|
*
|
7
9
|
* Create a new EntityReference element on the +document+ with +name+
|
8
10
|
*/
|
9
|
-
static VALUE
|
11
|
+
static VALUE
|
12
|
+
new (int argc, VALUE *argv, VALUE klass)
|
10
13
|
{
|
11
14
|
xmlDocPtr xml_doc;
|
12
15
|
xmlNodePtr node;
|
@@ -20,33 +23,28 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
|
|
20
23
|
Data_Get_Struct(document, xmlDoc, xml_doc);
|
21
24
|
|
22
25
|
node = xmlNewReference(
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
+
xml_doc,
|
27
|
+
(const xmlChar *)StringValueCStr(name)
|
28
|
+
);
|
26
29
|
|
27
|
-
|
30
|
+
noko_xml_document_pin_node(node);
|
28
31
|
|
29
|
-
rb_node =
|
32
|
+
rb_node = noko_xml_node_wrap(klass, node);
|
30
33
|
rb_obj_call_init(rb_node, argc, argv);
|
31
34
|
|
32
|
-
if(rb_block_given_p()) rb_yield(rb_node);
|
35
|
+
if (rb_block_given_p()) { rb_yield(rb_node); }
|
33
36
|
|
34
37
|
return rb_node;
|
35
38
|
}
|
36
39
|
|
37
|
-
|
38
|
-
|
40
|
+
void
|
41
|
+
noko_init_xml_entity_reference()
|
39
42
|
{
|
40
|
-
|
41
|
-
VALUE xml = rb_define_module_under(nokogiri, "XML");
|
42
|
-
VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
|
43
|
-
|
43
|
+
assert(cNokogiriXmlNode);
|
44
44
|
/*
|
45
45
|
* EntityReference represents an EntityReference node in an xml document.
|
46
46
|
*/
|
47
|
-
|
48
|
-
|
49
|
-
cNokogiriXmlEntityReference = klass;
|
47
|
+
cNokogiriXmlEntityReference = rb_define_class_under(mNokogiriXml, "EntityReference", cNokogiriXmlNode);
|
50
48
|
|
51
|
-
rb_define_singleton_method(
|
49
|
+
rb_define_singleton_method(cNokogiriXmlEntityReference, "new", new, -1);
|
52
50
|
}
|
@@ -1,16 +1,35 @@
|
|
1
|
-
#include <
|
1
|
+
#include <nokogiri.h>
|
2
|
+
|
3
|
+
/*
|
4
|
+
* The lifecycle of a Namespace node is more complicated than other Nodes, for two reasons:
|
5
|
+
*
|
6
|
+
* 1. the underlying C structure has a different layout than all the other node structs, with the
|
7
|
+
* `_private` member where we store a pointer to Ruby object data not being in first position.
|
8
|
+
* 2. xmlNs structures returned in an xmlNodeset from an XPath query are copies of the document's
|
9
|
+
* namespaces, and so do not share the same memory lifecycle as everything else in a document.
|
10
|
+
*
|
11
|
+
* As a result of 1, you may see special handling of XML_NAMESPACE_DECL node types throughout the
|
12
|
+
* Nokogiri C code, though I intend to wrap up that logic in ruby_object_{get,set} functions
|
13
|
+
* shortly.
|
14
|
+
*
|
15
|
+
* As a result of 2, you will see we have special handling in this file and in xml_node_set.c to
|
16
|
+
* carefully manage the memory lifecycle of xmlNs structs to match the Ruby object's GC
|
17
|
+
* lifecycle. In xml_node_set.c we have local versions of xmlXPathNodeSetDel() and
|
18
|
+
* xmlXPathFreeNodeSet() that avoid freeing xmlNs structs in the node set. In this file, we decide
|
19
|
+
* whether or not to call dealloc_namespace() depending on whether the xmlNs struct appears to be
|
20
|
+
* in an xmlNodeSet (and thus the result of an XPath query) or not.
|
21
|
+
*
|
22
|
+
* Yes, this is madness.
|
23
|
+
*/
|
2
24
|
|
3
25
|
VALUE cNokogiriXmlNamespace ;
|
4
26
|
|
5
|
-
static void
|
27
|
+
static void
|
28
|
+
dealloc_namespace(xmlNsPtr ns)
|
6
29
|
{
|
7
30
|
/*
|
8
|
-
*
|
9
31
|
* this deallocator is only used for namespace nodes that are part of an xpath
|
10
|
-
* node set.
|
11
|
-
*
|
12
|
-
* see Nokogiri_wrap_xml_namespace() for more details.
|
13
|
-
*
|
32
|
+
* node set. see noko_xml_namespace_wrap().
|
14
33
|
*/
|
15
34
|
NOKOGIRI_DEBUG_START(ns) ;
|
16
35
|
if (ns->href) {
|
@@ -30,12 +49,13 @@ static void dealloc_namespace(xmlNsPtr ns)
|
|
30
49
|
*
|
31
50
|
* Get the prefix for this namespace. Returns +nil+ if there is no prefix.
|
32
51
|
*/
|
33
|
-
static VALUE
|
52
|
+
static VALUE
|
53
|
+
prefix(VALUE self)
|
34
54
|
{
|
35
55
|
xmlNsPtr ns;
|
36
56
|
|
37
57
|
Data_Get_Struct(self, xmlNs, ns);
|
38
|
-
if(!ns->prefix) return Qnil;
|
58
|
+
if (!ns->prefix) { return Qnil; }
|
39
59
|
|
40
60
|
return NOKOGIRI_STR_NEW2(ns->prefix);
|
41
61
|
}
|
@@ -46,66 +66,55 @@ static VALUE prefix(VALUE self)
|
|
46
66
|
*
|
47
67
|
* Get the href for this namespace
|
48
68
|
*/
|
49
|
-
static VALUE
|
69
|
+
static VALUE
|
70
|
+
href(VALUE self)
|
50
71
|
{
|
51
72
|
xmlNsPtr ns;
|
52
73
|
|
53
74
|
Data_Get_Struct(self, xmlNs, ns);
|
54
|
-
if(!ns->href) return Qnil;
|
75
|
+
if (!ns->href) { return Qnil; }
|
55
76
|
|
56
77
|
return NOKOGIRI_STR_NEW2(ns->href);
|
57
78
|
}
|
58
79
|
|
59
|
-
|
80
|
+
VALUE
|
81
|
+
noko_xml_namespace_wrap(xmlNsPtr c_namespace, xmlDocPtr c_document)
|
60
82
|
{
|
61
|
-
|
62
|
-
}
|
83
|
+
VALUE rb_namespace;
|
63
84
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
assert(doc->type == XML_DOCUMENT_NODE || doc->type == XML_HTML_DOCUMENT_NODE);
|
69
|
-
|
70
|
-
if (node->_private) return (VALUE)node->_private;
|
71
|
-
|
72
|
-
if (doc->type == XML_DOCUMENT_FRAG_NODE) doc = doc->doc;
|
85
|
+
if (c_namespace->_private) {
|
86
|
+
return (VALUE)c_namespace->_private;
|
87
|
+
}
|
73
88
|
|
74
|
-
if (
|
75
|
-
|
89
|
+
if (c_document) {
|
90
|
+
rb_namespace = Data_Wrap_Struct(cNokogiriXmlNamespace, 0, 0, c_namespace);
|
76
91
|
|
77
|
-
if (
|
78
|
-
|
79
|
-
|
80
|
-
* we need to make sure we manage this memory.
|
81
|
-
*
|
82
|
-
* see comments in xml_node_set.c for more details.
|
83
|
-
*/
|
84
|
-
ns = Data_Wrap_Struct(cNokogiriXmlNamespace, 0, dealloc_namespace, node);
|
85
|
-
} else {
|
86
|
-
ns = Data_Wrap_Struct(cNokogiriXmlNamespace, 0, 0, node);
|
87
|
-
node_cache = rb_iv_get(document, "@node_cache");
|
88
|
-
rb_ary_push(node_cache, ns);
|
92
|
+
if (DOC_RUBY_OBJECT_TEST(c_document)) {
|
93
|
+
rb_iv_set(rb_namespace, "@document", DOC_RUBY_OBJECT(c_document));
|
94
|
+
rb_ary_push(DOC_NODE_CACHE(c_document), rb_namespace);
|
89
95
|
}
|
90
|
-
|
91
|
-
rb_iv_set(ns, "@document", document);
|
92
96
|
} else {
|
93
|
-
|
97
|
+
rb_namespace = Data_Wrap_Struct(cNokogiriXmlNamespace, 0, dealloc_namespace, c_namespace);
|
94
98
|
}
|
95
99
|
|
96
|
-
|
100
|
+
c_namespace->_private = (void *)rb_namespace;
|
101
|
+
|
102
|
+
return rb_namespace;
|
103
|
+
}
|
97
104
|
|
98
|
-
|
105
|
+
VALUE
|
106
|
+
noko_xml_namespace_wrap_xpath_copy(xmlNsPtr c_namespace)
|
107
|
+
{
|
108
|
+
return noko_xml_namespace_wrap(c_namespace, NULL);
|
99
109
|
}
|
100
110
|
|
101
|
-
void
|
111
|
+
void
|
112
|
+
noko_init_xml_namespace()
|
102
113
|
{
|
103
|
-
|
104
|
-
VALUE xml = rb_define_module_under(nokogiri, "XML");
|
105
|
-
VALUE klass = rb_define_class_under(xml, "Namespace", rb_cObject);
|
114
|
+
cNokogiriXmlNamespace = rb_define_class_under(mNokogiriXml, "Namespace", rb_cObject);
|
106
115
|
|
107
|
-
cNokogiriXmlNamespace
|
116
|
+
rb_undef_alloc_func(cNokogiriXmlNamespace);
|
108
117
|
|
109
|
-
rb_define_method(
|
110
|
-
rb_define_method(
|
118
|
+
rb_define_method(cNokogiriXmlNamespace, "prefix", prefix, 0);
|
119
|
+
rb_define_method(cNokogiriXmlNamespace, "href", href, 0);
|
111
120
|
}
|
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,25 +15,28 @@ 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;
|
18
|
-
if(doc->type == XML_DOCUMENT_NODE || doc->type == XML_HTML_DOCUMENT_NODE) {
|
19
|
-
if(DOC_RUBY_OBJECT_TEST(doc)) {
|
22
|
+
if (doc->type == XML_DOCUMENT_NODE || doc->type == XML_HTML_DOCUMENT_NODE) {
|
23
|
+
if (DOC_RUBY_OBJECT_TEST(doc)) {
|
20
24
|
rb_gc_mark(DOC_RUBY_OBJECT(doc));
|
21
25
|
}
|
22
|
-
} else if(node->doc->_private) {
|
26
|
+
} else if (node->doc->_private) {
|
23
27
|
rb_gc_mark((VALUE)doc->_private);
|
24
28
|
}
|
25
29
|
}
|
26
30
|
|
27
31
|
/* :nodoc: */
|
28
|
-
typedef xmlNodePtr
|
32
|
+
typedef xmlNodePtr(*pivot_reparentee_func)(xmlNodePtr, xmlNodePtr);
|
29
33
|
|
30
34
|
/* :nodoc: */
|
31
|
-
static void
|
35
|
+
static void
|
36
|
+
relink_namespace(xmlNodePtr reparented)
|
32
37
|
{
|
33
38
|
xmlNodePtr child;
|
39
|
+
xmlAttrPtr attr;
|
34
40
|
|
35
41
|
if (reparented->type != XML_ATTRIBUTE_NODE &&
|
36
42
|
reparented->type != XML_ELEMENT_NODE) { return; }
|
@@ -42,7 +48,7 @@ static void relink_namespace(xmlNodePtr reparented)
|
|
42
48
|
name = xmlSplitQName2(reparented->name, &prefix);
|
43
49
|
|
44
50
|
if (reparented->type == XML_ATTRIBUTE_NODE) {
|
45
|
-
if (prefix == NULL || strcmp((char*)prefix, XMLNS_PREFIX) == 0) {
|
51
|
+
if (prefix == NULL || strcmp((char *)prefix, XMLNS_PREFIX) == 0) {
|
46
52
|
xmlFree(name);
|
47
53
|
xmlFree(prefix);
|
48
54
|
return;
|
@@ -63,11 +69,6 @@ static void relink_namespace(xmlNodePtr reparented)
|
|
63
69
|
/* Avoid segv when relinking against unlinked nodes. */
|
64
70
|
if (reparented->type != XML_ELEMENT_NODE || !reparented->parent) { return; }
|
65
71
|
|
66
|
-
/* Make sure that our reparented node has the correct namespaces */
|
67
|
-
if (!reparented->ns && reparented->doc != (xmlDocPtr)reparented->parent) {
|
68
|
-
xmlSetNs(reparented, reparented->parent->ns);
|
69
|
-
}
|
70
|
-
|
71
72
|
/* Search our parents for an existing definition */
|
72
73
|
if (reparented->nsDef) {
|
73
74
|
xmlNsPtr curr = reparented->nsDef;
|
@@ -87,7 +88,7 @@ static void relink_namespace(xmlNodePtr reparented)
|
|
87
88
|
} else {
|
88
89
|
reparented->nsDef = curr->next;
|
89
90
|
}
|
90
|
-
|
91
|
+
noko_xml_document_pin_namespace(curr, reparented->doc);
|
91
92
|
} else {
|
92
93
|
prev = curr;
|
93
94
|
}
|
@@ -127,16 +128,17 @@ static void relink_namespace(xmlNodePtr reparented)
|
|
127
128
|
}
|
128
129
|
|
129
130
|
if (reparented->type == XML_ELEMENT_NODE) {
|
130
|
-
|
131
|
-
while(NULL !=
|
132
|
-
relink_namespace(
|
133
|
-
|
131
|
+
attr = reparented->properties;
|
132
|
+
while (NULL != attr) {
|
133
|
+
relink_namespace((xmlNodePtr)attr);
|
134
|
+
attr = attr->next;
|
134
135
|
}
|
135
136
|
}
|
136
137
|
}
|
137
138
|
|
138
139
|
/* :nodoc: */
|
139
|
-
static xmlNodePtr
|
140
|
+
static xmlNodePtr
|
141
|
+
xmlReplaceNodeWrapper(xmlNodePtr pivot, xmlNodePtr new_node)
|
140
142
|
{
|
141
143
|
xmlNodePtr retval ;
|
142
144
|
|
@@ -160,16 +162,17 @@ static xmlNodePtr xmlReplaceNodeWrapper(xmlNodePtr pivot, xmlNodePtr new_node)
|
|
160
162
|
}
|
161
163
|
|
162
164
|
/* :nodoc: */
|
163
|
-
static VALUE
|
165
|
+
static VALUE
|
166
|
+
reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_reparentee_func prf)
|
164
167
|
{
|
165
168
|
VALUE reparented_obj ;
|
166
|
-
xmlNodePtr reparentee, pivot, reparented, next_text, new_next_text, parent ;
|
169
|
+
xmlNodePtr reparentee, original_reparentee, pivot, reparented, next_text, new_next_text, parent ;
|
167
170
|
int original_ns_prefix_is_default = 0 ;
|
168
171
|
|
169
|
-
if(!rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlNode)) {
|
172
|
+
if (!rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlNode)) {
|
170
173
|
rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node");
|
171
174
|
}
|
172
|
-
if(rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlDocument)) {
|
175
|
+
if (rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlDocument)) {
|
173
176
|
rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node");
|
174
177
|
}
|
175
178
|
|
@@ -190,66 +193,66 @@ static VALUE reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_rep
|
|
190
193
|
|
191
194
|
if (parent) {
|
192
195
|
switch (parent->type) {
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
196
|
+
case XML_DOCUMENT_NODE:
|
197
|
+
case XML_HTML_DOCUMENT_NODE:
|
198
|
+
switch (reparentee->type) {
|
199
|
+
case XML_ELEMENT_NODE:
|
200
|
+
case XML_PI_NODE:
|
201
|
+
case XML_COMMENT_NODE:
|
202
|
+
case XML_DOCUMENT_TYPE_NODE:
|
203
|
+
/*
|
204
|
+
* The DOM specification says no to adding text-like nodes
|
205
|
+
* directly to a document, but we allow it for compatibility.
|
206
|
+
*/
|
207
|
+
case XML_TEXT_NODE:
|
208
|
+
case XML_CDATA_SECTION_NODE:
|
209
|
+
case XML_ENTITY_REF_NODE:
|
210
|
+
goto ok;
|
211
|
+
default:
|
212
|
+
break;
|
213
|
+
}
|
209
214
|
break;
|
210
|
-
|
211
|
-
break;
|
212
|
-
case XML_DOCUMENT_FRAG_NODE:
|
213
|
-
case XML_ENTITY_REF_NODE:
|
214
|
-
case XML_ELEMENT_NODE:
|
215
|
-
switch (reparentee->type) {
|
216
|
-
case XML_ELEMENT_NODE:
|
217
|
-
case XML_PI_NODE:
|
218
|
-
case XML_COMMENT_NODE:
|
219
|
-
case XML_TEXT_NODE:
|
220
|
-
case XML_CDATA_SECTION_NODE:
|
215
|
+
case XML_DOCUMENT_FRAG_NODE:
|
221
216
|
case XML_ENTITY_REF_NODE:
|
222
|
-
|
223
|
-
|
217
|
+
case XML_ELEMENT_NODE:
|
218
|
+
switch (reparentee->type) {
|
219
|
+
case XML_ELEMENT_NODE:
|
220
|
+
case XML_PI_NODE:
|
221
|
+
case XML_COMMENT_NODE:
|
222
|
+
case XML_TEXT_NODE:
|
223
|
+
case XML_CDATA_SECTION_NODE:
|
224
|
+
case XML_ENTITY_REF_NODE:
|
225
|
+
goto ok;
|
226
|
+
default:
|
227
|
+
break;
|
228
|
+
}
|
229
|
+
break;
|
230
|
+
case XML_ATTRIBUTE_NODE:
|
231
|
+
switch (reparentee->type) {
|
232
|
+
case XML_TEXT_NODE:
|
233
|
+
case XML_ENTITY_REF_NODE:
|
234
|
+
goto ok;
|
235
|
+
default:
|
236
|
+
break;
|
237
|
+
}
|
224
238
|
break;
|
225
|
-
}
|
226
|
-
break;
|
227
|
-
case XML_ATTRIBUTE_NODE:
|
228
|
-
switch (reparentee->type) {
|
229
239
|
case XML_TEXT_NODE:
|
230
|
-
|
231
|
-
|
240
|
+
/*
|
241
|
+
* xmlAddChild() breaks the DOM specification in that it allows
|
242
|
+
* adding a text node to another, in which case text nodes are
|
243
|
+
* coalesced, but since our JRuby version does not support such
|
244
|
+
* operation, we should inhibit it.
|
245
|
+
*/
|
246
|
+
break;
|
232
247
|
default:
|
233
248
|
break;
|
234
|
-
}
|
235
|
-
break;
|
236
|
-
case XML_TEXT_NODE:
|
237
|
-
/*
|
238
|
-
* xmlAddChild() breaks the DOM specification in that it allows
|
239
|
-
* adding a text node to another, in which case text nodes are
|
240
|
-
* coalesced, but since our JRuby version does not support such
|
241
|
-
* operation, we should inhibit it.
|
242
|
-
*/
|
243
|
-
break;
|
244
|
-
default:
|
245
|
-
break;
|
246
249
|
}
|
247
250
|
|
248
251
|
rb_raise(rb_eArgError, "cannot reparent %s there", rb_obj_classname(reparentee_obj));
|
249
252
|
}
|
250
253
|
|
251
254
|
ok:
|
252
|
-
|
255
|
+
original_reparentee = reparentee;
|
253
256
|
|
254
257
|
if (reparentee->doc != pivot->doc || reparentee->type == XML_TEXT_NODE) {
|
255
258
|
/*
|
@@ -290,7 +293,7 @@ ok:
|
|
290
293
|
original_ns_prefix_is_default = 1;
|
291
294
|
}
|
292
295
|
|
293
|
-
|
296
|
+
noko_xml_document_pin_node(reparentee);
|
294
297
|
|
295
298
|
if (!(reparentee = xmlDocCopyNode(reparentee, pivot->doc, 1))) {
|
296
299
|
rb_raise(rb_eRuntimeError, "Could not reparent node (xmlDocCopyNode)");
|
@@ -301,11 +304,13 @@ ok:
|
|
301
304
|
* issue #391, where new node's prefix may become the string "default"
|
302
305
|
* see libxml2 tree.c xmlNewReconciliedNs which implements this behavior.
|
303
306
|
*/
|
304
|
-
xmlFree((xmlChar*)reparentee->ns->prefix);
|
307
|
+
xmlFree((xmlChar *)reparentee->ns->prefix);
|
305
308
|
reparentee->ns->prefix = NULL;
|
306
309
|
}
|
307
310
|
}
|
308
311
|
|
312
|
+
xmlUnlinkNode(original_reparentee);
|
313
|
+
|
309
314
|
if (prf != xmlAddPrevSibling && prf != xmlAddNextSibling
|
310
315
|
&& reparentee->type == XML_TEXT_NODE && pivot->next && pivot->next->type == XML_TEXT_NODE) {
|
311
316
|
/*
|
@@ -330,12 +335,12 @@ ok:
|
|
330
335
|
new_next_text = xmlDocCopyNode(next_text, pivot->doc, 1) ;
|
331
336
|
|
332
337
|
xmlUnlinkNode(next_text);
|
333
|
-
|
338
|
+
noko_xml_document_pin_node(next_text);
|
334
339
|
|
335
340
|
xmlAddNextSibling(pivot, new_next_text);
|
336
341
|
}
|
337
342
|
|
338
|
-
if(!(reparented = (*prf)(pivot, reparentee))) {
|
343
|
+
if (!(reparented = (*prf)(pivot, reparentee))) {
|
339
344
|
rb_raise(rb_eRuntimeError, "Could not reparent node");
|
340
345
|
}
|
341
346
|
|
@@ -348,9 +353,9 @@ ok:
|
|
348
353
|
|
349
354
|
relink_namespace(reparented);
|
350
355
|
|
351
|
-
reparented_obj =
|
356
|
+
reparented_obj = noko_xml_node_wrap(Qnil, reparented);
|
352
357
|
|
353
|
-
rb_funcall(reparented_obj,
|
358
|
+
rb_funcall(reparented_obj, id_decorate_bang, 0);
|
354
359
|
|
355
360
|
return reparented_obj ;
|
356
361
|
}
|
@@ -362,7 +367,8 @@ ok:
|
|
362
367
|
*
|
363
368
|
* Get the document for this Node
|
364
369
|
*/
|
365
|
-
static VALUE
|
370
|
+
static VALUE
|
371
|
+
document(VALUE self)
|
366
372
|
{
|
367
373
|
xmlNodePtr node;
|
368
374
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -375,7 +381,8 @@ static VALUE document(VALUE self)
|
|
375
381
|
*
|
376
382
|
* Get the internal pointer number
|
377
383
|
*/
|
378
|
-
static VALUE
|
384
|
+
static VALUE
|
385
|
+
pointer_id(VALUE self)
|
379
386
|
{
|
380
387
|
xmlNodePtr node;
|
381
388
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -389,7 +396,8 @@ static VALUE pointer_id(VALUE self)
|
|
389
396
|
*
|
390
397
|
* Encode any special characters in +string+
|
391
398
|
*/
|
392
|
-
static VALUE
|
399
|
+
static VALUE
|
400
|
+
encode_special_chars(VALUE self, VALUE string)
|
393
401
|
{
|
394
402
|
xmlNodePtr node;
|
395
403
|
xmlChar *encoded;
|
@@ -419,7 +427,8 @@ static VALUE encode_special_chars(VALUE self, VALUE string)
|
|
419
427
|
* doc.create_internal_subset("chapter", nil, "chapter.dtd")
|
420
428
|
* # => <!DOCTYPE chapter SYSTEM "chapter.dtd">
|
421
429
|
*/
|
422
|
-
static VALUE
|
430
|
+
static VALUE
|
431
|
+
create_internal_subset(VALUE self, VALUE name, VALUE external_id, VALUE system_id)
|
423
432
|
{
|
424
433
|
xmlNodePtr node;
|
425
434
|
xmlDocPtr doc;
|
@@ -429,7 +438,7 @@ static VALUE create_internal_subset(VALUE self, VALUE name, VALUE external_id, V
|
|
429
438
|
|
430
439
|
doc = node->doc;
|
431
440
|
|
432
|
-
if(xmlGetIntSubset(doc)) {
|
441
|
+
if (xmlGetIntSubset(doc)) {
|
433
442
|
rb_raise(rb_eRuntimeError, "Document already has an internal subset");
|
434
443
|
}
|
435
444
|
|
@@ -440,9 +449,9 @@ static VALUE create_internal_subset(VALUE self, VALUE name, VALUE external_id, V
|
|
440
449
|
NIL_P(system_id) ? NULL : (const xmlChar *)StringValueCStr(system_id)
|
441
450
|
);
|
442
451
|
|
443
|
-
if(!dtd) { return Qnil; }
|
452
|
+
if (!dtd) { return Qnil; }
|
444
453
|
|
445
|
-
return
|
454
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)dtd);
|
446
455
|
}
|
447
456
|
|
448
457
|
/*
|
@@ -451,7 +460,8 @@ static VALUE create_internal_subset(VALUE self, VALUE name, VALUE external_id, V
|
|
451
460
|
*
|
452
461
|
* Create an external subset
|
453
462
|
*/
|
454
|
-
static VALUE
|
463
|
+
static VALUE
|
464
|
+
create_external_subset(VALUE self, VALUE name, VALUE external_id, VALUE system_id)
|
455
465
|
{
|
456
466
|
xmlNodePtr node;
|
457
467
|
xmlDocPtr doc;
|
@@ -461,7 +471,7 @@ static VALUE create_external_subset(VALUE self, VALUE name, VALUE external_id, V
|
|
461
471
|
|
462
472
|
doc = node->doc;
|
463
473
|
|
464
|
-
if(doc->extSubset) {
|
474
|
+
if (doc->extSubset) {
|
465
475
|
rb_raise(rb_eRuntimeError, "Document already has an external subset");
|
466
476
|
}
|
467
477
|
|
@@ -472,9 +482,9 @@ static VALUE create_external_subset(VALUE self, VALUE name, VALUE external_id, V
|
|
472
482
|
NIL_P(system_id) ? NULL : (const xmlChar *)StringValueCStr(system_id)
|
473
483
|
);
|
474
484
|
|
475
|
-
if(!dtd) { return Qnil; }
|
485
|
+
if (!dtd) { return Qnil; }
|
476
486
|
|
477
|
-
return
|
487
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)dtd);
|
478
488
|
}
|
479
489
|
|
480
490
|
/*
|
@@ -483,7 +493,8 @@ static VALUE create_external_subset(VALUE self, VALUE name, VALUE external_id, V
|
|
483
493
|
*
|
484
494
|
* Get the external subset
|
485
495
|
*/
|
486
|
-
static VALUE
|
496
|
+
static VALUE
|
497
|
+
external_subset(VALUE self)
|
487
498
|
{
|
488
499
|
xmlNodePtr node;
|
489
500
|
xmlDocPtr doc;
|
@@ -491,14 +502,14 @@ static VALUE external_subset(VALUE self)
|
|
491
502
|
|
492
503
|
Data_Get_Struct(self, xmlNode, node);
|
493
504
|
|
494
|
-
if(!node->doc) { return Qnil; }
|
505
|
+
if (!node->doc) { return Qnil; }
|
495
506
|
|
496
507
|
doc = node->doc;
|
497
508
|
dtd = doc->extSubset;
|
498
509
|
|
499
|
-
if(!dtd) { return Qnil; }
|
510
|
+
if (!dtd) { return Qnil; }
|
500
511
|
|
501
|
-
return
|
512
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)dtd);
|
502
513
|
}
|
503
514
|
|
504
515
|
/*
|
@@ -507,7 +518,8 @@ static VALUE external_subset(VALUE self)
|
|
507
518
|
*
|
508
519
|
* Get the internal subset
|
509
520
|
*/
|
510
|
-
static VALUE
|
521
|
+
static VALUE
|
522
|
+
internal_subset(VALUE self)
|
511
523
|
{
|
512
524
|
xmlNodePtr node;
|
513
525
|
xmlDocPtr doc;
|
@@ -515,14 +527,14 @@ static VALUE internal_subset(VALUE self)
|
|
515
527
|
|
516
528
|
Data_Get_Struct(self, xmlNode, node);
|
517
529
|
|
518
|
-
if(!node->doc) { return Qnil; }
|
530
|
+
if (!node->doc) { return Qnil; }
|
519
531
|
|
520
532
|
doc = node->doc;
|
521
533
|
dtd = xmlGetIntSubset(doc);
|
522
534
|
|
523
|
-
if(!dtd) { return Qnil; }
|
535
|
+
if (!dtd) { return Qnil; }
|
524
536
|
|
525
|
-
return
|
537
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)dtd);
|
526
538
|
}
|
527
539
|
|
528
540
|
/*
|
@@ -537,7 +549,8 @@ static VALUE internal_subset(VALUE self)
|
|
537
549
|
* node's parent document. Defaults to the current node's document.
|
538
550
|
* current document.
|
539
551
|
*/
|
540
|
-
static VALUE
|
552
|
+
static VALUE
|
553
|
+
duplicate_node(int argc, VALUE *argv, VALUE self)
|
541
554
|
{
|
542
555
|
VALUE r_level, r_new_parent_doc;
|
543
556
|
int level;
|
@@ -561,11 +574,11 @@ static VALUE duplicate_node(int argc, VALUE *argv, VALUE self)
|
|
561
574
|
}
|
562
575
|
|
563
576
|
dup = xmlDocCopyNode(node, new_parent_doc, level);
|
564
|
-
if(dup == NULL) { return Qnil; }
|
577
|
+
if (dup == NULL) { return Qnil; }
|
565
578
|
|
566
|
-
|
579
|
+
noko_xml_document_pin_node(dup);
|
567
580
|
|
568
|
-
return
|
581
|
+
return noko_xml_node_wrap(rb_obj_class(self), dup);
|
569
582
|
}
|
570
583
|
|
571
584
|
/*
|
@@ -574,12 +587,13 @@ static VALUE duplicate_node(int argc, VALUE *argv, VALUE self)
|
|
574
587
|
*
|
575
588
|
* Unlink this node from its current context.
|
576
589
|
*/
|
577
|
-
static VALUE
|
590
|
+
static VALUE
|
591
|
+
unlink_node(VALUE self)
|
578
592
|
{
|
579
593
|
xmlNodePtr node;
|
580
594
|
Data_Get_Struct(self, xmlNode, node);
|
581
595
|
xmlUnlinkNode(node);
|
582
|
-
|
596
|
+
noko_xml_document_pin_node(node);
|
583
597
|
return self;
|
584
598
|
}
|
585
599
|
|
@@ -589,7 +603,8 @@ static VALUE unlink_node(VALUE self)
|
|
589
603
|
*
|
590
604
|
* Is this node blank?
|
591
605
|
*/
|
592
|
-
static VALUE
|
606
|
+
static VALUE
|
607
|
+
blank_eh(VALUE self)
|
593
608
|
{
|
594
609
|
xmlNodePtr node;
|
595
610
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -602,15 +617,16 @@ static VALUE blank_eh(VALUE self)
|
|
602
617
|
*
|
603
618
|
* Returns the next sibling node
|
604
619
|
*/
|
605
|
-
static VALUE
|
620
|
+
static VALUE
|
621
|
+
next_sibling(VALUE self)
|
606
622
|
{
|
607
623
|
xmlNodePtr node, sibling;
|
608
624
|
Data_Get_Struct(self, xmlNode, node);
|
609
625
|
|
610
626
|
sibling = node->next;
|
611
|
-
if(!sibling) { return Qnil; }
|
627
|
+
if (!sibling) { return Qnil; }
|
612
628
|
|
613
|
-
return
|
629
|
+
return noko_xml_node_wrap(Qnil, sibling) ;
|
614
630
|
}
|
615
631
|
|
616
632
|
/*
|
@@ -619,15 +635,16 @@ static VALUE next_sibling(VALUE self)
|
|
619
635
|
*
|
620
636
|
* Returns the previous sibling node
|
621
637
|
*/
|
622
|
-
static VALUE
|
638
|
+
static VALUE
|
639
|
+
previous_sibling(VALUE self)
|
623
640
|
{
|
624
641
|
xmlNodePtr node, sibling;
|
625
642
|
Data_Get_Struct(self, xmlNode, node);
|
626
643
|
|
627
644
|
sibling = node->prev;
|
628
|
-
if(!sibling) { return Qnil; }
|
645
|
+
if (!sibling) { return Qnil; }
|
629
646
|
|
630
|
-
return
|
647
|
+
return noko_xml_node_wrap(Qnil, sibling);
|
631
648
|
}
|
632
649
|
|
633
650
|
/*
|
@@ -636,15 +653,16 @@ static VALUE previous_sibling(VALUE self)
|
|
636
653
|
*
|
637
654
|
* Returns the next Nokogiri::XML::Element type sibling node.
|
638
655
|
*/
|
639
|
-
static VALUE
|
656
|
+
static VALUE
|
657
|
+
next_element(VALUE self)
|
640
658
|
{
|
641
659
|
xmlNodePtr node, sibling;
|
642
660
|
Data_Get_Struct(self, xmlNode, node);
|
643
661
|
|
644
662
|
sibling = xmlNextElementSibling(node);
|
645
|
-
if(!sibling) { return Qnil; }
|
663
|
+
if (!sibling) { return Qnil; }
|
646
664
|
|
647
|
-
return
|
665
|
+
return noko_xml_node_wrap(Qnil, sibling);
|
648
666
|
}
|
649
667
|
|
650
668
|
/*
|
@@ -653,7 +671,8 @@ static VALUE next_element(VALUE self)
|
|
653
671
|
*
|
654
672
|
* Returns the previous Nokogiri::XML::Element type sibling node.
|
655
673
|
*/
|
656
|
-
static VALUE
|
674
|
+
static VALUE
|
675
|
+
previous_element(VALUE self)
|
657
676
|
{
|
658
677
|
xmlNodePtr node, sibling;
|
659
678
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -662,23 +681,24 @@ static VALUE previous_element(VALUE self)
|
|
662
681
|
* note that we don't use xmlPreviousElementSibling here because it's buggy pre-2.7.7.
|
663
682
|
*/
|
664
683
|
sibling = node->prev;
|
665
|
-
if(!sibling) { return Qnil; }
|
684
|
+
if (!sibling) { return Qnil; }
|
666
685
|
|
667
|
-
while(sibling && sibling->type != XML_ELEMENT_NODE) {
|
686
|
+
while (sibling && sibling->type != XML_ELEMENT_NODE) {
|
668
687
|
sibling = sibling->prev;
|
669
688
|
}
|
670
689
|
|
671
|
-
return sibling ?
|
690
|
+
return sibling ? noko_xml_node_wrap(Qnil, sibling) : Qnil ;
|
672
691
|
}
|
673
692
|
|
674
693
|
/* :nodoc: */
|
675
|
-
static VALUE
|
694
|
+
static VALUE
|
695
|
+
replace(VALUE self, VALUE new_node)
|
676
696
|
{
|
677
697
|
VALUE reparent = reparent_node_with(self, new_node, xmlReplaceNodeWrapper);
|
678
698
|
|
679
699
|
xmlNodePtr pivot;
|
680
700
|
Data_Get_Struct(self, xmlNode, pivot);
|
681
|
-
|
701
|
+
noko_xml_document_pin_node(pivot);
|
682
702
|
|
683
703
|
return reparent;
|
684
704
|
}
|
@@ -689,7 +709,8 @@ static VALUE replace(VALUE self, VALUE new_node)
|
|
689
709
|
*
|
690
710
|
* Get the list of children for this node as a NodeSet
|
691
711
|
*/
|
692
|
-
static VALUE
|
712
|
+
static VALUE
|
713
|
+
children(VALUE self)
|
693
714
|
{
|
694
715
|
xmlNodePtr node;
|
695
716
|
xmlNodePtr child;
|
@@ -704,15 +725,15 @@ static VALUE children(VALUE self)
|
|
704
725
|
|
705
726
|
document = DOC_RUBY_OBJECT(node->doc);
|
706
727
|
|
707
|
-
if(!child) { return
|
728
|
+
if (!child) { return noko_xml_node_set_wrap(set, document); }
|
708
729
|
|
709
730
|
child = child->next;
|
710
|
-
while(NULL != child) {
|
731
|
+
while (NULL != child) {
|
711
732
|
xmlXPathNodeSetAddUnique(set, child);
|
712
733
|
child = child->next;
|
713
734
|
}
|
714
735
|
|
715
|
-
node_set =
|
736
|
+
node_set = noko_xml_node_set_wrap(set, document);
|
716
737
|
|
717
738
|
return node_set;
|
718
739
|
}
|
@@ -728,7 +749,8 @@ static VALUE children(VALUE self)
|
|
728
749
|
*
|
729
750
|
* @doc.root.element_children.all? { |x| x.element? } # => true
|
730
751
|
*/
|
731
|
-
static VALUE
|
752
|
+
static VALUE
|
753
|
+
element_children(VALUE self)
|
732
754
|
{
|
733
755
|
xmlNodePtr node;
|
734
756
|
xmlNodePtr child;
|
@@ -743,15 +765,15 @@ static VALUE element_children(VALUE self)
|
|
743
765
|
|
744
766
|
document = DOC_RUBY_OBJECT(node->doc);
|
745
767
|
|
746
|
-
if(!child) { return
|
768
|
+
if (!child) { return noko_xml_node_set_wrap(set, document); }
|
747
769
|
|
748
770
|
child = xmlNextElementSibling(child);
|
749
|
-
while(NULL != child) {
|
771
|
+
while (NULL != child) {
|
750
772
|
xmlXPathNodeSetAddUnique(set, child);
|
751
773
|
child = xmlNextElementSibling(child);
|
752
774
|
}
|
753
775
|
|
754
|
-
node_set =
|
776
|
+
node_set = noko_xml_node_set_wrap(set, document);
|
755
777
|
|
756
778
|
return node_set;
|
757
779
|
}
|
@@ -762,15 +784,16 @@ static VALUE element_children(VALUE self)
|
|
762
784
|
*
|
763
785
|
* Returns the child node
|
764
786
|
*/
|
765
|
-
static VALUE
|
787
|
+
static VALUE
|
788
|
+
child(VALUE self)
|
766
789
|
{
|
767
790
|
xmlNodePtr node, child;
|
768
791
|
Data_Get_Struct(self, xmlNode, node);
|
769
792
|
|
770
793
|
child = node->children;
|
771
|
-
if(!child) { return Qnil; }
|
794
|
+
if (!child) { return Qnil; }
|
772
795
|
|
773
|
-
return
|
796
|
+
return noko_xml_node_wrap(Qnil, child);
|
774
797
|
}
|
775
798
|
|
776
799
|
/*
|
@@ -783,15 +806,16 @@ static VALUE child(VALUE self)
|
|
783
806
|
*
|
784
807
|
* @doc.root.first_element_child.element? # => true
|
785
808
|
*/
|
786
|
-
static VALUE
|
809
|
+
static VALUE
|
810
|
+
first_element_child(VALUE self)
|
787
811
|
{
|
788
812
|
xmlNodePtr node, child;
|
789
813
|
Data_Get_Struct(self, xmlNode, node);
|
790
814
|
|
791
815
|
child = xmlFirstElementChild(node);
|
792
|
-
if(!child) { return Qnil; }
|
816
|
+
if (!child) { return Qnil; }
|
793
817
|
|
794
|
-
return
|
818
|
+
return noko_xml_node_wrap(Qnil, child);
|
795
819
|
}
|
796
820
|
|
797
821
|
/*
|
@@ -804,15 +828,16 @@ static VALUE first_element_child(VALUE self)
|
|
804
828
|
*
|
805
829
|
* @doc.root.last_element_child.element? # => true
|
806
830
|
*/
|
807
|
-
static VALUE
|
831
|
+
static VALUE
|
832
|
+
last_element_child(VALUE self)
|
808
833
|
{
|
809
834
|
xmlNodePtr node, child;
|
810
835
|
Data_Get_Struct(self, xmlNode, node);
|
811
836
|
|
812
837
|
child = xmlLastElementChild(node);
|
813
|
-
if(!child) { return Qnil; }
|
838
|
+
if (!child) { return Qnil; }
|
814
839
|
|
815
|
-
return
|
840
|
+
return noko_xml_node_wrap(Qnil, child);
|
816
841
|
}
|
817
842
|
|
818
843
|
/*
|
@@ -821,11 +846,12 @@ static VALUE last_element_child(VALUE self)
|
|
821
846
|
*
|
822
847
|
* Returns true if +attribute+ is set
|
823
848
|
*/
|
824
|
-
static VALUE
|
849
|
+
static VALUE
|
850
|
+
key_eh(VALUE self, VALUE attribute)
|
825
851
|
{
|
826
852
|
xmlNodePtr node;
|
827
853
|
Data_Get_Struct(self, xmlNode, node);
|
828
|
-
if(xmlHasProp(node, (xmlChar *)StringValueCStr(attribute))) {
|
854
|
+
if (xmlHasProp(node, (xmlChar *)StringValueCStr(attribute))) {
|
829
855
|
return Qtrue;
|
830
856
|
}
|
831
857
|
return Qfalse;
|
@@ -837,12 +863,13 @@ static VALUE key_eh(VALUE self, VALUE attribute)
|
|
837
863
|
*
|
838
864
|
* Returns true if +attribute+ is set with +namespace+
|
839
865
|
*/
|
840
|
-
static VALUE
|
866
|
+
static VALUE
|
867
|
+
namespaced_key_eh(VALUE self, VALUE attribute, VALUE namespace)
|
841
868
|
{
|
842
869
|
xmlNodePtr node;
|
843
870
|
Data_Get_Struct(self, xmlNode, node);
|
844
|
-
if(xmlHasNsProp(node, (xmlChar *)StringValueCStr(attribute),
|
845
|
-
|
871
|
+
if (xmlHasNsProp(node, (xmlChar *)StringValueCStr(attribute),
|
872
|
+
NIL_P(namespace) ? NULL : (xmlChar *)StringValueCStr(namespace))) {
|
846
873
|
return Qtrue;
|
847
874
|
}
|
848
875
|
return Qfalse;
|
@@ -854,7 +881,8 @@ static VALUE namespaced_key_eh(VALUE self, VALUE attribute, VALUE namespace)
|
|
854
881
|
*
|
855
882
|
* Set the +property+ to +value+
|
856
883
|
*/
|
857
|
-
static VALUE
|
884
|
+
static VALUE
|
885
|
+
set(VALUE self, VALUE property, VALUE value)
|
858
886
|
{
|
859
887
|
xmlNodePtr node, cur;
|
860
888
|
xmlAttrPtr prop;
|
@@ -867,13 +895,13 @@ static VALUE set(VALUE self, VALUE property, VALUE value)
|
|
867
895
|
* We can avoid this by unlinking these nodes first.
|
868
896
|
*/
|
869
897
|
if (node->type != XML_ELEMENT_NODE) {
|
870
|
-
return(Qnil);
|
898
|
+
return (Qnil);
|
871
899
|
}
|
872
900
|
prop = xmlHasProp(node, (xmlChar *)StringValueCStr(property));
|
873
901
|
if (prop && prop->children) {
|
874
902
|
for (cur = prop->children; cur; cur = cur->next) {
|
875
903
|
if (cur->_private) {
|
876
|
-
|
904
|
+
noko_xml_document_pin_node(cur);
|
877
905
|
xmlUnlinkNode(cur);
|
878
906
|
}
|
879
907
|
}
|
@@ -891,7 +919,8 @@ static VALUE set(VALUE self, VALUE property, VALUE value)
|
|
891
919
|
*
|
892
920
|
* Get the value for +attribute+
|
893
921
|
*/
|
894
|
-
static VALUE
|
922
|
+
static VALUE
|
923
|
+
get(VALUE self, VALUE rattribute)
|
895
924
|
{
|
896
925
|
xmlNodePtr node;
|
897
926
|
xmlChar *value = 0;
|
@@ -917,7 +946,7 @@ static VALUE get(VALUE self, VALUE rattribute)
|
|
917
946
|
if (ns) {
|
918
947
|
value = xmlGetNsProp(node, attr_name, ns->href);
|
919
948
|
} else {
|
920
|
-
value = xmlGetProp(node, (xmlChar*)StringValueCStr(rattribute));
|
949
|
+
value = xmlGetProp(node, (xmlChar *)StringValueCStr(rattribute));
|
921
950
|
}
|
922
951
|
} else {
|
923
952
|
value = xmlGetNoNsProp(node, attribute);
|
@@ -938,14 +967,15 @@ static VALUE get(VALUE self, VALUE rattribute)
|
|
938
967
|
*
|
939
968
|
* Set the namespace to +namespace+
|
940
969
|
*/
|
941
|
-
static VALUE
|
970
|
+
static VALUE
|
971
|
+
set_namespace(VALUE self, VALUE namespace)
|
942
972
|
{
|
943
973
|
xmlNodePtr node;
|
944
974
|
xmlNsPtr ns = NULL;
|
945
975
|
|
946
976
|
Data_Get_Struct(self, xmlNode, node);
|
947
977
|
|
948
|
-
if(!NIL_P(namespace)) {
|
978
|
+
if (!NIL_P(namespace)) {
|
949
979
|
Data_Get_Struct(namespace, xmlNs, ns);
|
950
980
|
}
|
951
981
|
|
@@ -960,15 +990,16 @@ static VALUE set_namespace(VALUE self, VALUE namespace)
|
|
960
990
|
*
|
961
991
|
* Get the attribute node with +name+
|
962
992
|
*/
|
963
|
-
static VALUE
|
993
|
+
static VALUE
|
994
|
+
attr(VALUE self, VALUE name)
|
964
995
|
{
|
965
996
|
xmlNodePtr node;
|
966
997
|
xmlAttrPtr prop;
|
967
998
|
Data_Get_Struct(self, xmlNode, node);
|
968
999
|
prop = xmlHasProp(node, (xmlChar *)StringValueCStr(name));
|
969
1000
|
|
970
|
-
if(! prop) { return Qnil; }
|
971
|
-
return
|
1001
|
+
if (! prop) { return Qnil; }
|
1002
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)prop);
|
972
1003
|
}
|
973
1004
|
|
974
1005
|
/*
|
@@ -977,7 +1008,8 @@ static VALUE attr(VALUE self, VALUE name)
|
|
977
1008
|
*
|
978
1009
|
* Get the attribute node with +name+ and +namespace+
|
979
1010
|
*/
|
980
|
-
static VALUE
|
1011
|
+
static VALUE
|
1012
|
+
attribute_with_ns(VALUE self, VALUE name, VALUE namespace)
|
981
1013
|
{
|
982
1014
|
xmlNodePtr node;
|
983
1015
|
xmlAttrPtr prop;
|
@@ -985,28 +1017,23 @@ static VALUE attribute_with_ns(VALUE self, VALUE name, VALUE namespace)
|
|
985
1017
|
prop = xmlHasNsProp(node, (xmlChar *)StringValueCStr(name),
|
986
1018
|
NIL_P(namespace) ? NULL : (xmlChar *)StringValueCStr(namespace));
|
987
1019
|
|
988
|
-
if(! prop) { return Qnil; }
|
989
|
-
return
|
1020
|
+
if (! prop) { return Qnil; }
|
1021
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)prop);
|
990
1022
|
}
|
991
1023
|
|
992
1024
|
/*
|
993
|
-
*
|
994
|
-
*
|
995
|
-
*
|
996
|
-
* returns a list containing the Node attributes.
|
1025
|
+
* @overload attribute_nodes()
|
1026
|
+
* Get the attributes for a Node
|
1027
|
+
* @return [Array<Nokogiri::XML::Attr>] containing the Node's attributes.
|
997
1028
|
*/
|
998
|
-
static VALUE
|
1029
|
+
static VALUE
|
1030
|
+
attribute_nodes(VALUE rb_node)
|
999
1031
|
{
|
1000
|
-
|
1001
|
-
xmlNodePtr node;
|
1002
|
-
VALUE attr;
|
1032
|
+
xmlNodePtr c_node;
|
1003
1033
|
|
1004
|
-
Data_Get_Struct(
|
1034
|
+
Data_Get_Struct(rb_node, xmlNode, c_node);
|
1005
1035
|
|
1006
|
-
|
1007
|
-
Nokogiri_xml_node_properties(node, attr);
|
1008
|
-
|
1009
|
-
return attr ;
|
1036
|
+
return noko_xml_node_attrs(c_node);
|
1010
1037
|
}
|
1011
1038
|
|
1012
1039
|
|
@@ -1017,16 +1044,17 @@ static VALUE attribute_nodes(VALUE self)
|
|
1017
1044
|
* returns the namespace of the element or attribute node as a Namespace
|
1018
1045
|
* object, or nil if there is no namespace for the element or attribute.
|
1019
1046
|
*/
|
1020
|
-
static VALUE
|
1047
|
+
static VALUE
|
1048
|
+
noko_xml_node_namespace(VALUE rb_node)
|
1021
1049
|
{
|
1022
|
-
xmlNodePtr
|
1023
|
-
Data_Get_Struct(
|
1050
|
+
xmlNodePtr c_node ;
|
1051
|
+
Data_Get_Struct(rb_node, xmlNode, c_node);
|
1024
1052
|
|
1025
|
-
if (
|
1026
|
-
|
1027
|
-
}
|
1053
|
+
if (c_node->ns) {
|
1054
|
+
return noko_xml_namespace_wrap(c_node->ns, c_node->doc);
|
1055
|
+
}
|
1028
1056
|
|
1029
|
-
return Qnil ;
|
1057
|
+
return Qnil ;
|
1030
1058
|
}
|
1031
1059
|
|
1032
1060
|
/*
|
@@ -1035,27 +1063,27 @@ return Qnil ;
|
|
1035
1063
|
*
|
1036
1064
|
* 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=").
|
1037
1065
|
*/
|
1038
|
-
static VALUE
|
1066
|
+
static VALUE
|
1067
|
+
namespace_definitions(VALUE rb_node)
|
1039
1068
|
{
|
1040
1069
|
/* this code in the mode of xmlHasProp() */
|
1041
|
-
xmlNodePtr
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
Data_Get_Struct(self, xmlNode, node);
|
1046
|
-
|
1047
|
-
list = rb_ary_new();
|
1070
|
+
xmlNodePtr c_node ;
|
1071
|
+
xmlNsPtr c_namespace;
|
1072
|
+
VALUE definitions = rb_ary_new();
|
1048
1073
|
|
1049
|
-
|
1074
|
+
Data_Get_Struct(rb_node, xmlNode, c_node);
|
1050
1075
|
|
1051
|
-
|
1076
|
+
c_namespace = c_node->nsDef;
|
1077
|
+
if (!c_namespace) {
|
1078
|
+
return definitions;
|
1079
|
+
}
|
1052
1080
|
|
1053
|
-
while(
|
1054
|
-
rb_ary_push(
|
1055
|
-
|
1081
|
+
while (c_namespace != NULL) {
|
1082
|
+
rb_ary_push(definitions, noko_xml_namespace_wrap(c_namespace, c_node->doc));
|
1083
|
+
c_namespace = c_namespace->next;
|
1056
1084
|
}
|
1057
1085
|
|
1058
|
-
return
|
1086
|
+
return definitions;
|
1059
1087
|
}
|
1060
1088
|
|
1061
1089
|
/*
|
@@ -1067,26 +1095,27 @@ static VALUE namespace_definitions(VALUE self)
|
|
1067
1095
|
* namespaces ("xmlns=" style) for self are included in this array; Default
|
1068
1096
|
* namespaces for ancestors, however, are not. See also #namespaces
|
1069
1097
|
*/
|
1070
|
-
static VALUE
|
1098
|
+
static VALUE
|
1099
|
+
namespace_scopes(VALUE rb_node)
|
1071
1100
|
{
|
1072
|
-
xmlNodePtr
|
1073
|
-
|
1074
|
-
|
1101
|
+
xmlNodePtr c_node ;
|
1102
|
+
xmlNsPtr *namespaces;
|
1103
|
+
VALUE scopes = rb_ary_new();
|
1075
1104
|
int j;
|
1076
1105
|
|
1077
|
-
Data_Get_Struct(
|
1078
|
-
|
1079
|
-
list = rb_ary_new();
|
1080
|
-
ns_list = xmlGetNsList(node->doc, node);
|
1106
|
+
Data_Get_Struct(rb_node, xmlNode, c_node);
|
1081
1107
|
|
1082
|
-
|
1108
|
+
namespaces = xmlGetNsList(c_node->doc, c_node);
|
1109
|
+
if (!namespaces) {
|
1110
|
+
return scopes;
|
1111
|
+
}
|
1083
1112
|
|
1084
|
-
for (j = 0 ;
|
1085
|
-
rb_ary_push(
|
1113
|
+
for (j = 0 ; namespaces[j] != NULL ; ++j) {
|
1114
|
+
rb_ary_push(scopes, noko_xml_namespace_wrap(namespaces[j], c_node->doc));
|
1086
1115
|
}
|
1087
1116
|
|
1088
|
-
xmlFree(
|
1089
|
-
return
|
1117
|
+
xmlFree(namespaces);
|
1118
|
+
return scopes;
|
1090
1119
|
}
|
1091
1120
|
|
1092
1121
|
/*
|
@@ -1095,7 +1124,8 @@ static VALUE namespace_scopes(VALUE self)
|
|
1095
1124
|
*
|
1096
1125
|
* Get the type for this Node
|
1097
1126
|
*/
|
1098
|
-
static VALUE
|
1127
|
+
static VALUE
|
1128
|
+
node_type(VALUE self)
|
1099
1129
|
{
|
1100
1130
|
xmlNodePtr node;
|
1101
1131
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -1108,7 +1138,8 @@ static VALUE node_type(VALUE self)
|
|
1108
1138
|
*
|
1109
1139
|
* Set the content for this Node
|
1110
1140
|
*/
|
1111
|
-
static VALUE
|
1141
|
+
static VALUE
|
1142
|
+
set_native_content(VALUE self, VALUE content)
|
1112
1143
|
{
|
1113
1144
|
xmlNodePtr node, child, next ;
|
1114
1145
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -1117,7 +1148,7 @@ static VALUE set_native_content(VALUE self, VALUE content)
|
|
1117
1148
|
while (NULL != child) {
|
1118
1149
|
next = child->next ;
|
1119
1150
|
xmlUnlinkNode(child) ;
|
1120
|
-
|
1151
|
+
noko_xml_document_pin_node(child);
|
1121
1152
|
child = next ;
|
1122
1153
|
}
|
1123
1154
|
|
@@ -1132,15 +1163,16 @@ static VALUE set_native_content(VALUE self, VALUE content)
|
|
1132
1163
|
* Returns the plaintext content for this Node. Note that entities will always
|
1133
1164
|
* be expanded in the returned string.
|
1134
1165
|
*/
|
1135
|
-
static VALUE
|
1166
|
+
static VALUE
|
1167
|
+
get_native_content(VALUE self)
|
1136
1168
|
{
|
1137
1169
|
xmlNodePtr node;
|
1138
|
-
xmlChar *
|
1170
|
+
xmlChar *content;
|
1139
1171
|
|
1140
1172
|
Data_Get_Struct(self, xmlNode, node);
|
1141
1173
|
|
1142
1174
|
content = xmlNodeGetContent(node);
|
1143
|
-
if(content) {
|
1175
|
+
if (content) {
|
1144
1176
|
VALUE rval = NOKOGIRI_STR_NEW2(content);
|
1145
1177
|
xmlFree(content);
|
1146
1178
|
return rval;
|
@@ -1154,13 +1186,14 @@ static VALUE get_native_content(VALUE self)
|
|
1154
1186
|
*
|
1155
1187
|
* Set the language of a node, i.e. the values of the xml:lang attribute.
|
1156
1188
|
*/
|
1157
|
-
static VALUE
|
1189
|
+
static VALUE
|
1190
|
+
set_lang(VALUE self_rb, VALUE lang_rb)
|
1158
1191
|
{
|
1159
1192
|
xmlNodePtr self ;
|
1160
|
-
xmlChar*
|
1193
|
+
xmlChar *lang ;
|
1161
1194
|
|
1162
1195
|
Data_Get_Struct(self_rb, xmlNode, self);
|
1163
|
-
lang = (xmlChar*)StringValueCStr(lang_rb);
|
1196
|
+
lang = (xmlChar *)StringValueCStr(lang_rb);
|
1164
1197
|
|
1165
1198
|
xmlNodeSetLang(self, lang);
|
1166
1199
|
|
@@ -1174,10 +1207,11 @@ static VALUE set_lang(VALUE self_rb, VALUE lang_rb)
|
|
1174
1207
|
* Searches the language of a node, i.e. the values of the xml:lang attribute or
|
1175
1208
|
* the one carried by the nearest ancestor.
|
1176
1209
|
*/
|
1177
|
-
static VALUE
|
1210
|
+
static VALUE
|
1211
|
+
get_lang(VALUE self_rb)
|
1178
1212
|
{
|
1179
1213
|
xmlNodePtr self ;
|
1180
|
-
xmlChar*
|
1214
|
+
xmlChar *lang ;
|
1181
1215
|
VALUE lang_rb ;
|
1182
1216
|
|
1183
1217
|
Data_Get_Struct(self_rb, xmlNode, self);
|
@@ -1193,7 +1227,8 @@ static VALUE get_lang(VALUE self_rb)
|
|
1193
1227
|
}
|
1194
1228
|
|
1195
1229
|
/* :nodoc: */
|
1196
|
-
static VALUE
|
1230
|
+
static VALUE
|
1231
|
+
add_child(VALUE self, VALUE new_child)
|
1197
1232
|
{
|
1198
1233
|
return reparent_node_with(self, new_child, xmlAddChild);
|
1199
1234
|
}
|
@@ -1204,15 +1239,16 @@ static VALUE add_child(VALUE self, VALUE new_child)
|
|
1204
1239
|
*
|
1205
1240
|
* Get the parent Node for this Node
|
1206
1241
|
*/
|
1207
|
-
static VALUE
|
1242
|
+
static VALUE
|
1243
|
+
get_parent(VALUE self)
|
1208
1244
|
{
|
1209
1245
|
xmlNodePtr node, parent;
|
1210
1246
|
Data_Get_Struct(self, xmlNode, node);
|
1211
1247
|
|
1212
1248
|
parent = node->parent;
|
1213
|
-
if(!parent) { return Qnil; }
|
1249
|
+
if (!parent) { return Qnil; }
|
1214
1250
|
|
1215
|
-
return
|
1251
|
+
return noko_xml_node_wrap(Qnil, parent) ;
|
1216
1252
|
}
|
1217
1253
|
|
1218
1254
|
/*
|
@@ -1221,11 +1257,12 @@ static VALUE get_parent(VALUE self)
|
|
1221
1257
|
*
|
1222
1258
|
* Set the name for this Node
|
1223
1259
|
*/
|
1224
|
-
static VALUE
|
1260
|
+
static VALUE
|
1261
|
+
set_name(VALUE self, VALUE new_name)
|
1225
1262
|
{
|
1226
1263
|
xmlNodePtr node;
|
1227
1264
|
Data_Get_Struct(self, xmlNode, node);
|
1228
|
-
xmlNodeSetName(node, (xmlChar*)StringValueCStr(new_name));
|
1265
|
+
xmlNodeSetName(node, (xmlChar *)StringValueCStr(new_name));
|
1229
1266
|
return new_name;
|
1230
1267
|
}
|
1231
1268
|
|
@@ -1235,11 +1272,12 @@ static VALUE set_name(VALUE self, VALUE new_name)
|
|
1235
1272
|
*
|
1236
1273
|
* Returns the name for this Node
|
1237
1274
|
*/
|
1238
|
-
static VALUE
|
1275
|
+
static VALUE
|
1276
|
+
get_name(VALUE self)
|
1239
1277
|
{
|
1240
1278
|
xmlNodePtr node;
|
1241
1279
|
Data_Get_Struct(self, xmlNode, node);
|
1242
|
-
if(node->name) {
|
1280
|
+
if (node->name) {
|
1243
1281
|
return NOKOGIRI_STR_NEW2(node->name);
|
1244
1282
|
}
|
1245
1283
|
return Qnil;
|
@@ -1251,28 +1289,39 @@ static VALUE get_name(VALUE self)
|
|
1251
1289
|
*
|
1252
1290
|
* Returns the path associated with this Node
|
1253
1291
|
*/
|
1254
|
-
static VALUE
|
1292
|
+
static VALUE
|
1293
|
+
noko_xml_node_path(VALUE rb_node)
|
1255
1294
|
{
|
1256
|
-
xmlNodePtr
|
1257
|
-
xmlChar *
|
1295
|
+
xmlNodePtr c_node;
|
1296
|
+
xmlChar *c_path ;
|
1258
1297
|
VALUE rval;
|
1259
1298
|
|
1260
|
-
Data_Get_Struct(
|
1299
|
+
Data_Get_Struct(rb_node, xmlNode, c_node);
|
1300
|
+
|
1301
|
+
c_path = xmlGetNodePath(c_node);
|
1302
|
+
if (c_path == NULL) {
|
1303
|
+
// see https://github.com/sparklemotion/nokogiri/issues/2250
|
1304
|
+
// this behavior is clearly undesirable, but is what libxml <= 2.9.10 returned, and so we
|
1305
|
+
// do this for now to preserve the behavior across libxml2 versions.
|
1306
|
+
rval = NOKOGIRI_STR_NEW2("?");
|
1307
|
+
} else {
|
1308
|
+
rval = NOKOGIRI_STR_NEW2(c_path);
|
1309
|
+
xmlFree(c_path);
|
1310
|
+
}
|
1261
1311
|
|
1262
|
-
path = xmlGetNodePath(node);
|
1263
|
-
rval = NOKOGIRI_STR_NEW2(path);
|
1264
|
-
xmlFree(path);
|
1265
1312
|
return rval ;
|
1266
1313
|
}
|
1267
1314
|
|
1268
1315
|
/* :nodoc: */
|
1269
|
-
static VALUE
|
1316
|
+
static VALUE
|
1317
|
+
add_next_sibling(VALUE self, VALUE new_sibling)
|
1270
1318
|
{
|
1271
1319
|
return reparent_node_with(self, new_sibling, xmlAddNextSibling) ;
|
1272
1320
|
}
|
1273
1321
|
|
1274
1322
|
/* :nodoc: */
|
1275
|
-
static VALUE
|
1323
|
+
static VALUE
|
1324
|
+
add_previous_sibling(VALUE self, VALUE new_sibling)
|
1276
1325
|
{
|
1277
1326
|
return reparent_node_with(self, new_sibling, xmlAddPrevSibling) ;
|
1278
1327
|
}
|
@@ -1283,7 +1332,8 @@ static VALUE add_previous_sibling(VALUE self, VALUE new_sibling)
|
|
1283
1332
|
*
|
1284
1333
|
* Write this Node to +io+ with +encoding+ and +options+
|
1285
1334
|
*/
|
1286
|
-
static VALUE
|
1335
|
+
static VALUE
|
1336
|
+
native_write_to(
|
1287
1337
|
VALUE self,
|
1288
1338
|
VALUE io,
|
1289
1339
|
VALUE encoding,
|
@@ -1292,7 +1342,7 @@ static VALUE native_write_to(
|
|
1292
1342
|
)
|
1293
1343
|
{
|
1294
1344
|
xmlNodePtr node;
|
1295
|
-
const char *
|
1345
|
+
const char *before_indent;
|
1296
1346
|
xmlSaveCtxtPtr savectx;
|
1297
1347
|
|
1298
1348
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -1304,8 +1354,8 @@ static VALUE native_write_to(
|
|
1304
1354
|
xmlTreeIndentString = StringValueCStr(indent_string);
|
1305
1355
|
|
1306
1356
|
savectx = xmlSaveToIO(
|
1307
|
-
(xmlOutputWriteCallback)
|
1308
|
-
(xmlOutputCloseCallback)
|
1357
|
+
(xmlOutputWriteCallback)noko_io_write,
|
1358
|
+
(xmlOutputCloseCallback)noko_io_close,
|
1309
1359
|
(void *)io,
|
1310
1360
|
RTEST(encoding) ? StringValueCStr(encoding) : NULL,
|
1311
1361
|
(int)NUM2INT(options)
|
@@ -1324,7 +1374,8 @@ static VALUE native_write_to(
|
|
1324
1374
|
*
|
1325
1375
|
* Returns the line for this Node
|
1326
1376
|
*/
|
1327
|
-
static VALUE
|
1377
|
+
static VALUE
|
1378
|
+
line(VALUE self)
|
1328
1379
|
{
|
1329
1380
|
xmlNodePtr node;
|
1330
1381
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -1338,12 +1389,13 @@ static VALUE line(VALUE self)
|
|
1338
1389
|
*
|
1339
1390
|
* Sets the line for this Node. num must be less than 65535.
|
1340
1391
|
*/
|
1341
|
-
static VALUE
|
1392
|
+
static VALUE
|
1393
|
+
set_line(VALUE self, VALUE num)
|
1342
1394
|
{
|
1343
1395
|
xmlNodePtr node;
|
1344
|
-
Data_Get_Struct(self, xmlNode, node);
|
1345
|
-
|
1346
1396
|
int value = NUM2INT(num);
|
1397
|
+
|
1398
|
+
Data_Get_Struct(self, xmlNode, node);
|
1347
1399
|
if (value < 65535) {
|
1348
1400
|
node->line = value;
|
1349
1401
|
}
|
@@ -1362,45 +1414,47 @@ static VALUE set_line(VALUE self, VALUE num)
|
|
1362
1414
|
* show up in #attributes, but they will be included as an xmlns attribute
|
1363
1415
|
* when the node is serialized to XML.
|
1364
1416
|
*/
|
1365
|
-
static VALUE
|
1417
|
+
static VALUE
|
1418
|
+
add_namespace_definition(VALUE rb_node, VALUE rb_prefix, VALUE rb_href)
|
1366
1419
|
{
|
1367
|
-
xmlNodePtr
|
1368
|
-
xmlNsPtr
|
1420
|
+
xmlNodePtr c_node, element;
|
1421
|
+
xmlNsPtr c_namespace;
|
1422
|
+
const xmlChar *c_prefix = (const xmlChar *)(NIL_P(rb_prefix) ? NULL : StringValueCStr(rb_prefix));
|
1369
1423
|
|
1370
|
-
Data_Get_Struct(
|
1371
|
-
|
1424
|
+
Data_Get_Struct(rb_node, xmlNode, c_node);
|
1425
|
+
element = c_node ;
|
1372
1426
|
|
1373
|
-
|
1374
|
-
node->doc,
|
1375
|
-
node,
|
1376
|
-
(const xmlChar *)(NIL_P(prefix) ? NULL : StringValueCStr(prefix))
|
1377
|
-
);
|
1427
|
+
c_namespace = xmlSearchNs(c_node->doc, c_node, c_prefix);
|
1378
1428
|
|
1379
|
-
if(!
|
1380
|
-
if (
|
1381
|
-
|
1429
|
+
if (!c_namespace) {
|
1430
|
+
if (c_node->type != XML_ELEMENT_NODE) {
|
1431
|
+
element = c_node->parent;
|
1382
1432
|
}
|
1383
|
-
|
1384
|
-
namespace,
|
1385
|
-
(const xmlChar *)StringValueCStr(href),
|
1386
|
-
(const xmlChar *)(NIL_P(prefix) ? NULL : StringValueCStr(prefix))
|
1387
|
-
);
|
1433
|
+
c_namespace = xmlNewNs(element, (const xmlChar *)StringValueCStr(rb_href), c_prefix);
|
1388
1434
|
}
|
1389
1435
|
|
1390
|
-
if (!
|
1436
|
+
if (!c_namespace) {
|
1437
|
+
return Qnil ;
|
1438
|
+
}
|
1391
1439
|
|
1392
|
-
if(NIL_P(
|
1440
|
+
if (NIL_P(rb_prefix) || c_node != element) {
|
1441
|
+
xmlSetNs(c_node, c_namespace);
|
1442
|
+
}
|
1393
1443
|
|
1394
|
-
return
|
1444
|
+
return noko_xml_namespace_wrap(c_namespace, c_node->doc);
|
1395
1445
|
}
|
1396
1446
|
|
1397
1447
|
/*
|
1398
|
-
*
|
1399
|
-
* new
|
1400
|
-
*
|
1401
|
-
*
|
1448
|
+
* @overload new(name, document)
|
1449
|
+
* Create a new node with +name+ sharing GC lifecycle with +document+.
|
1450
|
+
* @param name [String]
|
1451
|
+
* @param document [Nokogiri::XML::Document]
|
1452
|
+
* @yieldparam node [Nokogiri::XML::Node]
|
1453
|
+
* @return [Nokogiri::XML::Node]
|
1454
|
+
* @see Nokogiri::XML::Node#initialize
|
1402
1455
|
*/
|
1403
|
-
static VALUE
|
1456
|
+
static VALUE
|
1457
|
+
rb_xml_node_new(int argc, VALUE *argv, VALUE klass)
|
1404
1458
|
{
|
1405
1459
|
xmlDocPtr doc;
|
1406
1460
|
xmlNodePtr node;
|
@@ -1415,15 +1469,15 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
|
|
1415
1469
|
|
1416
1470
|
node = xmlNewNode(NULL, (xmlChar *)StringValueCStr(name));
|
1417
1471
|
node->doc = doc->doc;
|
1418
|
-
|
1472
|
+
noko_xml_document_pin_node(node);
|
1419
1473
|
|
1420
|
-
rb_node =
|
1474
|
+
rb_node = noko_xml_node_wrap(
|
1421
1475
|
klass == cNokogiriXmlNode ? (VALUE)NULL : klass,
|
1422
1476
|
node
|
1423
1477
|
);
|
1424
1478
|
rb_obj_call_init(rb_node, argc, argv);
|
1425
1479
|
|
1426
|
-
if(rb_block_given_p()) { rb_yield(rb_node); }
|
1480
|
+
if (rb_block_given_p()) { rb_yield(rb_node); }
|
1427
1481
|
|
1428
1482
|
return rb_node;
|
1429
1483
|
}
|
@@ -1434,7 +1488,8 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
|
|
1434
1488
|
*
|
1435
1489
|
* Returns the Node as html.
|
1436
1490
|
*/
|
1437
|
-
static VALUE
|
1491
|
+
static VALUE
|
1492
|
+
dump_html(VALUE self)
|
1438
1493
|
{
|
1439
1494
|
xmlBufferPtr buf ;
|
1440
1495
|
xmlNodePtr node ;
|
@@ -1455,7 +1510,8 @@ static VALUE dump_html(VALUE self)
|
|
1455
1510
|
*
|
1456
1511
|
* Compare this Node to +other+ with respect to their Document
|
1457
1512
|
*/
|
1458
|
-
static VALUE
|
1513
|
+
static VALUE
|
1514
|
+
compare(VALUE self, VALUE _other)
|
1459
1515
|
{
|
1460
1516
|
xmlNodePtr node, other;
|
1461
1517
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -1472,7 +1528,8 @@ static VALUE compare(VALUE self, VALUE _other)
|
|
1472
1528
|
* Loads and substitutes all xinclude elements below the node. The
|
1473
1529
|
* parser context will be initialized with +options+.
|
1474
1530
|
*/
|
1475
|
-
static VALUE
|
1531
|
+
static VALUE
|
1532
|
+
process_xincludes(VALUE self, VALUE options)
|
1476
1533
|
{
|
1477
1534
|
int rcode ;
|
1478
1535
|
xmlNodePtr node;
|
@@ -1488,7 +1545,7 @@ static VALUE process_xincludes(VALUE self, VALUE options)
|
|
1488
1545
|
xmlErrorPtr error;
|
1489
1546
|
|
1490
1547
|
error = xmlGetLastError();
|
1491
|
-
if(error) {
|
1548
|
+
if (error) {
|
1492
1549
|
rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
|
1493
1550
|
} else {
|
1494
1551
|
rb_raise(rb_eRuntimeError, "Could not perform xinclude substitution");
|
@@ -1500,7 +1557,8 @@ static VALUE process_xincludes(VALUE self, VALUE options)
|
|
1500
1557
|
|
1501
1558
|
|
1502
1559
|
/* TODO: DOCUMENT ME */
|
1503
|
-
static VALUE
|
1560
|
+
static VALUE
|
1561
|
+
in_context(VALUE self, VALUE _str, VALUE _options)
|
1504
1562
|
{
|
1505
1563
|
xmlNodePtr node, list = 0, tmp, child_iter, node_children, doc_children;
|
1506
1564
|
xmlNodeSetPtr set;
|
@@ -1581,12 +1639,12 @@ static VALUE in_context(VALUE self, VALUE _str, VALUE _options)
|
|
1581
1639
|
|
1582
1640
|
/* FIXME: This probably needs to handle more constants... */
|
1583
1641
|
switch (error) {
|
1584
|
-
|
1585
|
-
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
|
1642
|
+
case XML_ERR_INTERNAL_ERROR:
|
1643
|
+
case XML_ERR_NO_MEMORY:
|
1644
|
+
rb_raise(rb_eRuntimeError, "error parsing fragment (%d)", error);
|
1645
|
+
break;
|
1646
|
+
default:
|
1647
|
+
break;
|
1590
1648
|
}
|
1591
1649
|
|
1592
1650
|
set = xmlXPathNodeSetCreate(NULL);
|
@@ -1595,179 +1653,180 @@ static VALUE in_context(VALUE self, VALUE _str, VALUE _options)
|
|
1595
1653
|
tmp = list->next;
|
1596
1654
|
list->next = NULL;
|
1597
1655
|
xmlXPathNodeSetAddUnique(set, list);
|
1598
|
-
|
1656
|
+
noko_xml_document_pin_node(list);
|
1599
1657
|
list = tmp;
|
1600
1658
|
}
|
1601
1659
|
|
1602
|
-
return
|
1660
|
+
return noko_xml_node_set_wrap(set, doc);
|
1603
1661
|
}
|
1604
1662
|
|
1605
1663
|
|
1606
|
-
VALUE
|
1664
|
+
VALUE
|
1665
|
+
noko_xml_node_wrap(VALUE rb_class, xmlNodePtr c_node)
|
1607
1666
|
{
|
1608
|
-
VALUE
|
1609
|
-
VALUE node_cache = Qnil ;
|
1610
|
-
VALUE rb_node = Qnil ;
|
1667
|
+
VALUE rb_document, rb_node_cache, rb_node;
|
1611
1668
|
nokogiriTuplePtr node_has_a_document;
|
1612
|
-
xmlDocPtr
|
1669
|
+
xmlDocPtr c_doc;
|
1613
1670
|
void (*mark_method)(xmlNodePtr) = NULL ;
|
1614
1671
|
|
1615
|
-
assert(
|
1672
|
+
assert(c_node);
|
1616
1673
|
|
1617
|
-
if(
|
1618
|
-
return DOC_RUBY_OBJECT(
|
1674
|
+
if (c_node->type == XML_DOCUMENT_NODE || c_node->type == XML_HTML_DOCUMENT_NODE) {
|
1675
|
+
return DOC_RUBY_OBJECT(c_node->doc);
|
1619
1676
|
}
|
1620
1677
|
|
1621
1678
|
/* It's OK if the node doesn't have a fully-realized document (as in XML::Reader). */
|
1622
1679
|
/* see https://github.com/sparklemotion/nokogiri/issues/95 */
|
1623
1680
|
/* and https://github.com/sparklemotion/nokogiri/issues/439 */
|
1624
|
-
|
1625
|
-
if (
|
1626
|
-
node_has_a_document = DOC_RUBY_OBJECT_TEST(
|
1681
|
+
c_doc = c_node->doc;
|
1682
|
+
if (c_doc->type == XML_DOCUMENT_FRAG_NODE) { c_doc = c_doc->doc; }
|
1683
|
+
node_has_a_document = DOC_RUBY_OBJECT_TEST(c_doc);
|
1627
1684
|
|
1628
|
-
if(
|
1629
|
-
return (VALUE)
|
1685
|
+
if (c_node->_private && node_has_a_document) {
|
1686
|
+
return (VALUE)c_node->_private;
|
1630
1687
|
}
|
1631
1688
|
|
1632
|
-
if(!RTEST(
|
1633
|
-
switch(
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1642
|
-
|
1643
|
-
|
1644
|
-
|
1645
|
-
|
1646
|
-
|
1647
|
-
|
1648
|
-
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
1653
|
-
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1671
|
-
|
1689
|
+
if (!RTEST(rb_class)) {
|
1690
|
+
switch (c_node->type) {
|
1691
|
+
case XML_ELEMENT_NODE:
|
1692
|
+
rb_class = cNokogiriXmlElement;
|
1693
|
+
break;
|
1694
|
+
case XML_TEXT_NODE:
|
1695
|
+
rb_class = cNokogiriXmlText;
|
1696
|
+
break;
|
1697
|
+
case XML_ATTRIBUTE_NODE:
|
1698
|
+
rb_class = cNokogiriXmlAttr;
|
1699
|
+
break;
|
1700
|
+
case XML_ENTITY_REF_NODE:
|
1701
|
+
rb_class = cNokogiriXmlEntityReference;
|
1702
|
+
break;
|
1703
|
+
case XML_COMMENT_NODE:
|
1704
|
+
rb_class = cNokogiriXmlComment;
|
1705
|
+
break;
|
1706
|
+
case XML_DOCUMENT_FRAG_NODE:
|
1707
|
+
rb_class = cNokogiriXmlDocumentFragment;
|
1708
|
+
break;
|
1709
|
+
case XML_PI_NODE:
|
1710
|
+
rb_class = cNokogiriXmlProcessingInstruction;
|
1711
|
+
break;
|
1712
|
+
case XML_ENTITY_DECL:
|
1713
|
+
rb_class = cNokogiriXmlEntityDecl;
|
1714
|
+
break;
|
1715
|
+
case XML_CDATA_SECTION_NODE:
|
1716
|
+
rb_class = cNokogiriXmlCData;
|
1717
|
+
break;
|
1718
|
+
case XML_DTD_NODE:
|
1719
|
+
rb_class = cNokogiriXmlDtd;
|
1720
|
+
break;
|
1721
|
+
case XML_ATTRIBUTE_DECL:
|
1722
|
+
rb_class = cNokogiriXmlAttributeDecl;
|
1723
|
+
break;
|
1724
|
+
case XML_ELEMENT_DECL:
|
1725
|
+
rb_class = cNokogiriXmlElementDecl;
|
1726
|
+
break;
|
1727
|
+
default:
|
1728
|
+
rb_class = cNokogiriXmlNode;
|
1672
1729
|
}
|
1673
1730
|
}
|
1674
1731
|
|
1675
1732
|
mark_method = node_has_a_document ? mark : NULL ;
|
1676
1733
|
|
1677
|
-
rb_node = Data_Wrap_Struct(
|
1678
|
-
|
1734
|
+
rb_node = Data_Wrap_Struct(rb_class, mark_method, debug_node_dealloc, c_node) ;
|
1735
|
+
c_node->_private = (void *)rb_node;
|
1679
1736
|
|
1680
1737
|
if (node_has_a_document) {
|
1681
|
-
|
1682
|
-
|
1683
|
-
rb_ary_push(
|
1684
|
-
rb_funcall(
|
1738
|
+
rb_document = DOC_RUBY_OBJECT(c_doc);
|
1739
|
+
rb_node_cache = DOC_NODE_CACHE(c_doc);
|
1740
|
+
rb_ary_push(rb_node_cache, rb_node);
|
1741
|
+
rb_funcall(rb_document, id_decorate, 1, rb_node);
|
1685
1742
|
}
|
1686
1743
|
|
1687
1744
|
return rb_node ;
|
1688
1745
|
}
|
1689
1746
|
|
1690
1747
|
|
1691
|
-
|
1748
|
+
/*
|
1749
|
+
* return Array<Nokogiri::XML::Attr> containing the node's attributes
|
1750
|
+
*/
|
1751
|
+
VALUE
|
1752
|
+
noko_xml_node_attrs(xmlNodePtr c_node)
|
1692
1753
|
{
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1754
|
+
VALUE rb_properties = rb_ary_new();
|
1755
|
+
xmlAttrPtr c_property;
|
1756
|
+
|
1757
|
+
c_property = c_node->properties ;
|
1758
|
+
while (c_property != NULL) {
|
1759
|
+
rb_ary_push(rb_properties, noko_xml_node_wrap(Qnil, (xmlNodePtr)c_property));
|
1760
|
+
c_property = c_property->next ;
|
1698
1761
|
}
|
1699
|
-
}
|
1700
1762
|
|
1701
|
-
|
1702
|
-
|
1763
|
+
return rb_properties;
|
1764
|
+
}
|
1703
1765
|
|
1704
|
-
void
|
1766
|
+
void
|
1767
|
+
noko_init_xml_node()
|
1705
1768
|
{
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
cNokogiriXmlNode
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1716
|
-
rb_define_method(
|
1717
|
-
rb_define_method(
|
1718
|
-
rb_define_method(
|
1719
|
-
rb_define_method(
|
1720
|
-
rb_define_method(
|
1721
|
-
rb_define_method(
|
1722
|
-
rb_define_method(
|
1723
|
-
rb_define_method(
|
1724
|
-
rb_define_method(
|
1725
|
-
rb_define_method(
|
1726
|
-
rb_define_method(
|
1727
|
-
rb_define_method(
|
1728
|
-
rb_define_method(
|
1729
|
-
rb_define_method(
|
1730
|
-
rb_define_method(
|
1731
|
-
rb_define_method(
|
1732
|
-
rb_define_method(
|
1733
|
-
rb_define_method(
|
1734
|
-
rb_define_method(
|
1735
|
-
rb_define_method(
|
1736
|
-
rb_define_method(
|
1737
|
-
rb_define_method(
|
1738
|
-
rb_define_method(
|
1739
|
-
rb_define_method(
|
1740
|
-
rb_define_method(
|
1741
|
-
rb_define_method(
|
1742
|
-
rb_define_method(
|
1743
|
-
rb_define_method(
|
1744
|
-
rb_define_method(
|
1745
|
-
rb_define_method(
|
1746
|
-
rb_define_method(
|
1747
|
-
rb_define_method(
|
1748
|
-
rb_define_method(
|
1749
|
-
rb_define_method(
|
1750
|
-
rb_define_method(
|
1751
|
-
|
1752
|
-
|
1753
|
-
|
1754
|
-
|
1755
|
-
|
1756
|
-
rb_define_private_method(
|
1757
|
-
rb_define_private_method(
|
1758
|
-
rb_define_private_method(
|
1759
|
-
rb_define_private_method(
|
1760
|
-
rb_define_private_method(
|
1761
|
-
rb_define_private_method(
|
1762
|
-
rb_define_private_method(
|
1763
|
-
rb_define_private_method(
|
1764
|
-
|
1765
|
-
|
1766
|
-
|
1767
|
-
rb_define_private_method(klass, "compare", compare, 1);
|
1768
|
-
|
1769
|
-
decorate = rb_intern("decorate");
|
1770
|
-
decorate_bang = rb_intern("decorate!");
|
1769
|
+
cNokogiriXmlNode = rb_define_class_under(mNokogiriXml, "Node", rb_cObject);
|
1770
|
+
|
1771
|
+
rb_undef_alloc_func(cNokogiriXmlNode);
|
1772
|
+
|
1773
|
+
rb_define_singleton_method(cNokogiriXmlNode, "new", rb_xml_node_new, -1);
|
1774
|
+
|
1775
|
+
rb_define_method(cNokogiriXmlNode, "add_namespace_definition", add_namespace_definition, 2);
|
1776
|
+
rb_define_method(cNokogiriXmlNode, "node_name", get_name, 0);
|
1777
|
+
rb_define_method(cNokogiriXmlNode, "document", document, 0);
|
1778
|
+
rb_define_method(cNokogiriXmlNode, "node_name=", set_name, 1);
|
1779
|
+
rb_define_method(cNokogiriXmlNode, "parent", get_parent, 0);
|
1780
|
+
rb_define_method(cNokogiriXmlNode, "child", child, 0);
|
1781
|
+
rb_define_method(cNokogiriXmlNode, "first_element_child", first_element_child, 0);
|
1782
|
+
rb_define_method(cNokogiriXmlNode, "last_element_child", last_element_child, 0);
|
1783
|
+
rb_define_method(cNokogiriXmlNode, "children", children, 0);
|
1784
|
+
rb_define_method(cNokogiriXmlNode, "element_children", element_children, 0);
|
1785
|
+
rb_define_method(cNokogiriXmlNode, "next_sibling", next_sibling, 0);
|
1786
|
+
rb_define_method(cNokogiriXmlNode, "previous_sibling", previous_sibling, 0);
|
1787
|
+
rb_define_method(cNokogiriXmlNode, "next_element", next_element, 0);
|
1788
|
+
rb_define_method(cNokogiriXmlNode, "previous_element", previous_element, 0);
|
1789
|
+
rb_define_method(cNokogiriXmlNode, "node_type", node_type, 0);
|
1790
|
+
rb_define_method(cNokogiriXmlNode, "path", noko_xml_node_path, 0);
|
1791
|
+
rb_define_method(cNokogiriXmlNode, "key?", key_eh, 1);
|
1792
|
+
rb_define_method(cNokogiriXmlNode, "namespaced_key?", namespaced_key_eh, 2);
|
1793
|
+
rb_define_method(cNokogiriXmlNode, "blank?", blank_eh, 0);
|
1794
|
+
rb_define_method(cNokogiriXmlNode, "attribute_nodes", attribute_nodes, 0);
|
1795
|
+
rb_define_method(cNokogiriXmlNode, "attribute", attr, 1);
|
1796
|
+
rb_define_method(cNokogiriXmlNode, "attribute_with_ns", attribute_with_ns, 2);
|
1797
|
+
rb_define_method(cNokogiriXmlNode, "namespace", noko_xml_node_namespace, 0);
|
1798
|
+
rb_define_method(cNokogiriXmlNode, "namespace_definitions", namespace_definitions, 0);
|
1799
|
+
rb_define_method(cNokogiriXmlNode, "namespace_scopes", namespace_scopes, 0);
|
1800
|
+
rb_define_method(cNokogiriXmlNode, "encode_special_chars", encode_special_chars, 1);
|
1801
|
+
rb_define_method(cNokogiriXmlNode, "dup", duplicate_node, -1);
|
1802
|
+
rb_define_method(cNokogiriXmlNode, "unlink", unlink_node, 0);
|
1803
|
+
rb_define_method(cNokogiriXmlNode, "internal_subset", internal_subset, 0);
|
1804
|
+
rb_define_method(cNokogiriXmlNode, "external_subset", external_subset, 0);
|
1805
|
+
rb_define_method(cNokogiriXmlNode, "create_internal_subset", create_internal_subset, 3);
|
1806
|
+
rb_define_method(cNokogiriXmlNode, "create_external_subset", create_external_subset, 3);
|
1807
|
+
rb_define_method(cNokogiriXmlNode, "pointer_id", pointer_id, 0);
|
1808
|
+
rb_define_method(cNokogiriXmlNode, "line", line, 0);
|
1809
|
+
rb_define_method(cNokogiriXmlNode, "line=", set_line, 1);
|
1810
|
+
rb_define_method(cNokogiriXmlNode, "content", get_native_content, 0);
|
1811
|
+
rb_define_method(cNokogiriXmlNode, "native_content=", set_native_content, 1);
|
1812
|
+
rb_define_method(cNokogiriXmlNode, "lang", get_lang, 0);
|
1813
|
+
rb_define_method(cNokogiriXmlNode, "lang=", set_lang, 1);
|
1814
|
+
|
1815
|
+
rb_define_private_method(cNokogiriXmlNode, "process_xincludes", process_xincludes, 1);
|
1816
|
+
rb_define_private_method(cNokogiriXmlNode, "in_context", in_context, 2);
|
1817
|
+
rb_define_private_method(cNokogiriXmlNode, "add_child_node", add_child, 1);
|
1818
|
+
rb_define_private_method(cNokogiriXmlNode, "add_previous_sibling_node", add_previous_sibling, 1);
|
1819
|
+
rb_define_private_method(cNokogiriXmlNode, "add_next_sibling_node", add_next_sibling, 1);
|
1820
|
+
rb_define_private_method(cNokogiriXmlNode, "replace_node", replace, 1);
|
1821
|
+
rb_define_private_method(cNokogiriXmlNode, "dump_html", dump_html, 0);
|
1822
|
+
rb_define_private_method(cNokogiriXmlNode, "native_write_to", native_write_to, 4);
|
1823
|
+
rb_define_private_method(cNokogiriXmlNode, "get", get, 1);
|
1824
|
+
rb_define_private_method(cNokogiriXmlNode, "set", set, 2);
|
1825
|
+
rb_define_private_method(cNokogiriXmlNode, "set_namespace", set_namespace, 1);
|
1826
|
+
rb_define_private_method(cNokogiriXmlNode, "compare", compare, 1);
|
1827
|
+
|
1828
|
+
id_decorate = rb_intern("decorate");
|
1829
|
+
id_decorate_bang = rb_intern("decorate!");
|
1771
1830
|
}
|
1772
1831
|
|
1773
1832
|
/* vim: set noet sw=4 sws=4 */
|