nokogiri 1.11.3 → 1.13.8
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/Gemfile +2 -0
- data/LICENSE-DEPENDENCIES.md +243 -22
- data/LICENSE.md +1 -1
- data/README.md +14 -11
- data/bin/nokogiri +63 -50
- data/dependencies.yml +13 -64
- data/ext/nokogiri/depend +35 -34
- data/ext/nokogiri/extconf.rb +237 -133
- data/ext/nokogiri/gumbo.c +584 -0
- data/ext/nokogiri/{html_document.c → html4_document.c} +8 -8
- data/ext/nokogiri/{html_element_description.c → html4_element_description.c} +21 -19
- data/ext/nokogiri/{html_entity_lookup.c → html4_entity_lookup.c} +7 -7
- data/ext/nokogiri/{html_sax_parser_context.c → html4_sax_parser_context.c} +8 -8
- data/ext/nokogiri/{html_sax_push_parser.c → html4_sax_push_parser.c} +4 -4
- data/ext/nokogiri/libxml2_backwards_compat.c +30 -30
- data/ext/nokogiri/nokogiri.c +70 -38
- data/ext/nokogiri/nokogiri.h +27 -9
- data/ext/nokogiri/xml_attr.c +2 -2
- data/ext/nokogiri/xml_attribute_decl.c +3 -3
- data/ext/nokogiri/xml_cdata.c +1 -1
- data/ext/nokogiri/xml_document.c +50 -50
- data/ext/nokogiri/xml_document_fragment.c +0 -2
- data/ext/nokogiri/xml_dtd.c +10 -10
- data/ext/nokogiri/xml_element_content.c +2 -0
- data/ext/nokogiri/xml_element_decl.c +3 -3
- data/ext/nokogiri/xml_encoding_handler.c +31 -12
- data/ext/nokogiri/xml_entity_decl.c +5 -5
- data/ext/nokogiri/xml_namespace.c +4 -2
- data/ext/nokogiri/xml_node.c +833 -492
- data/ext/nokogiri/xml_node_set.c +24 -24
- data/ext/nokogiri/xml_reader.c +90 -11
- data/ext/nokogiri/xml_sax_parser.c +6 -6
- data/ext/nokogiri/xml_sax_parser_context.c +12 -3
- data/ext/nokogiri/xml_schema.c +5 -3
- data/ext/nokogiri/xml_text.c +1 -1
- data/ext/nokogiri/xml_xpath_context.c +110 -85
- data/ext/nokogiri/xslt_stylesheet.c +109 -10
- 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 +4875 -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/class_resolver.rb +67 -0
- data/lib/nokogiri/css/node.rb +9 -8
- data/lib/nokogiri/css/parser.rb +361 -342
- data/lib/nokogiri/css/parser.y +250 -245
- data/lib/nokogiri/css/parser_extras.rb +22 -20
- data/lib/nokogiri/css/syntax_error.rb +2 -1
- data/lib/nokogiri/css/tokenizer.rb +4 -3
- data/lib/nokogiri/css/tokenizer.rex +3 -2
- data/lib/nokogiri/css/xpath_visitor.rb +179 -82
- data/lib/nokogiri/css.rb +49 -17
- data/lib/nokogiri/decorators/slop.rb +8 -7
- data/lib/nokogiri/extension.rb +8 -3
- data/lib/nokogiri/gumbo.rb +15 -0
- data/lib/nokogiri/html.rb +37 -27
- data/lib/nokogiri/{html → html4}/builder.rb +3 -2
- data/lib/nokogiri/{html → html4}/document.rb +92 -81
- data/lib/nokogiri/{html → html4}/document_fragment.rb +13 -9
- data/lib/nokogiri/{html → html4}/element_description.rb +2 -1
- data/lib/nokogiri/html4/element_description_defaults.rb +578 -0
- data/lib/nokogiri/{html → html4}/entity_lookup.rb +3 -2
- data/lib/nokogiri/{html → html4}/sax/parser.rb +16 -16
- data/lib/nokogiri/html4/sax/parser_context.rb +20 -0
- data/lib/nokogiri/{html → html4}/sax/push_parser.rb +11 -11
- data/lib/nokogiri/html4.rb +46 -0
- data/lib/nokogiri/html5/document.rb +91 -0
- data/lib/nokogiri/html5/document_fragment.rb +83 -0
- data/lib/nokogiri/html5/node.rb +100 -0
- data/lib/nokogiri/html5.rb +478 -0
- data/lib/nokogiri/jruby/dependencies.rb +10 -9
- data/lib/nokogiri/syntax_error.rb +1 -0
- data/lib/nokogiri/version/constant.rb +2 -1
- data/lib/nokogiri/version/info.rb +31 -14
- data/lib/nokogiri/version.rb +1 -0
- data/lib/nokogiri/xml/attr.rb +5 -3
- data/lib/nokogiri/xml/attribute_decl.rb +2 -1
- data/lib/nokogiri/xml/builder.rb +71 -31
- data/lib/nokogiri/xml/cdata.rb +2 -1
- data/lib/nokogiri/xml/character_data.rb +1 -0
- data/lib/nokogiri/xml/document.rb +183 -96
- data/lib/nokogiri/xml/document_fragment.rb +41 -38
- data/lib/nokogiri/xml/dtd.rb +3 -2
- data/lib/nokogiri/xml/element_content.rb +1 -0
- data/lib/nokogiri/xml/element_decl.rb +2 -1
- data/lib/nokogiri/xml/entity_decl.rb +3 -2
- data/lib/nokogiri/xml/entity_reference.rb +1 -0
- data/lib/nokogiri/xml/namespace.rb +2 -0
- data/lib/nokogiri/xml/node/save_options.rb +9 -5
- data/lib/nokogiri/xml/node.rb +525 -354
- data/lib/nokogiri/xml/node_set.rb +50 -54
- data/lib/nokogiri/xml/notation.rb +12 -0
- data/lib/nokogiri/xml/parse_options.rb +13 -6
- data/lib/nokogiri/xml/pp/character_data.rb +8 -6
- data/lib/nokogiri/xml/pp/node.rb +24 -26
- data/lib/nokogiri/xml/pp.rb +3 -2
- data/lib/nokogiri/xml/processing_instruction.rb +2 -1
- data/lib/nokogiri/xml/reader.rb +20 -24
- data/lib/nokogiri/xml/relax_ng.rb +1 -0
- data/lib/nokogiri/xml/sax/document.rb +44 -49
- data/lib/nokogiri/xml/sax/parser.rb +37 -34
- data/lib/nokogiri/xml/sax/parser_context.rb +7 -3
- data/lib/nokogiri/xml/sax/push_parser.rb +5 -5
- data/lib/nokogiri/xml/sax.rb +5 -4
- data/lib/nokogiri/xml/schema.rb +7 -6
- data/lib/nokogiri/xml/searchable.rb +93 -62
- data/lib/nokogiri/xml/syntax_error.rb +5 -4
- data/lib/nokogiri/xml/text.rb +1 -0
- data/lib/nokogiri/xml/xpath/syntax_error.rb +2 -1
- data/lib/nokogiri/xml/xpath.rb +13 -1
- data/lib/nokogiri/xml/xpath_context.rb +2 -3
- data/lib/nokogiri/xml.rb +37 -37
- data/lib/nokogiri/xslt/stylesheet.rb +2 -1
- data/lib/nokogiri/xslt.rb +28 -20
- data/lib/nokogiri.rb +48 -43
- data/lib/xsd/xmlparser/nokogiri.rb +25 -24
- 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} +3 -3
- 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 +3040 -0
- data/patches/libxml2/0008-htmlParseComment-handle-abruptly-closed-comments.patch +61 -0
- data/patches/libxml2/0009-allow-wildcard-namespaces.patch +77 -0
- data/patches/libxslt/0001-update-automake-files-for-arm64.patch +2445 -1919
- data/ports/archives/libxml2-2.9.14.tar.xz +0 -0
- data/ports/archives/libxslt-1.1.35.tar.xz +0 -0
- metadata +204 -93
- data/lib/nokogiri/html/element_description_defaults.rb +0 -672
- 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/patches/libxml2/0010-parser.c-shrink-the-input-buffer-when-appropriate.patch +0 -70
- data/patches/libxml2/0011-update-automake-files-for-arm64.patch +0 -2511
- data/ports/archives/libxml2-2.9.10.tar.gz +0 -0
- data/ports/archives/libxslt-1.1.34.tar.gz +0 -0
data/ext/nokogiri/xml_node.c
CHANGED
@@ -1,23 +1,30 @@
|
|
1
1
|
#include <nokogiri.h>
|
2
2
|
|
3
|
-
|
3
|
+
// :stopdoc:
|
4
4
|
|
5
|
+
VALUE cNokogiriXmlNode ;
|
5
6
|
static ID id_decorate, id_decorate_bang;
|
6
7
|
|
8
|
+
typedef xmlNodePtr(*pivot_reparentee_func)(xmlNodePtr, xmlNodePtr);
|
9
|
+
|
7
10
|
#ifdef DEBUG
|
8
11
|
static void
|
9
|
-
|
12
|
+
_xml_node_dealloc(xmlNodePtr x)
|
10
13
|
{
|
11
14
|
NOKOGIRI_DEBUG_START(x)
|
12
15
|
NOKOGIRI_DEBUG_END(x)
|
13
16
|
}
|
14
17
|
#else
|
15
|
-
# define
|
18
|
+
# define _xml_node_dealloc 0
|
16
19
|
#endif
|
17
20
|
|
18
21
|
static void
|
19
|
-
|
22
|
+
_xml_node_mark(xmlNodePtr node)
|
20
23
|
{
|
24
|
+
if (!DOC_RUBY_OBJECT_TEST(node->doc)) {
|
25
|
+
return;
|
26
|
+
}
|
27
|
+
|
21
28
|
xmlDocPtr doc = node->doc;
|
22
29
|
if (doc->type == XML_DOCUMENT_NODE || doc->type == XML_HTML_DOCUMENT_NODE) {
|
23
30
|
if (DOC_RUBY_OBJECT_TEST(doc)) {
|
@@ -28,14 +35,37 @@ mark(xmlNodePtr node)
|
|
28
35
|
}
|
29
36
|
}
|
30
37
|
|
31
|
-
|
32
|
-
|
38
|
+
#ifdef HAVE_RB_GC_LOCATION
|
39
|
+
static void
|
40
|
+
_xml_node_update_references(xmlNodePtr node)
|
41
|
+
{
|
42
|
+
if (node->_private) {
|
43
|
+
node->_private = (void *)rb_gc_location((VALUE)node->_private);
|
44
|
+
}
|
45
|
+
}
|
46
|
+
#endif
|
47
|
+
|
48
|
+
typedef void (*gc_callback_t)(void *);
|
49
|
+
|
50
|
+
static const rb_data_type_t nokogiri_node_type = {
|
51
|
+
"Nokogiri/XMLNode",
|
52
|
+
{
|
53
|
+
(gc_callback_t)_xml_node_mark, (gc_callback_t)_xml_node_dealloc, 0,
|
54
|
+
#ifdef HAVE_RB_GC_LOCATION
|
55
|
+
(gc_callback_t)_xml_node_update_references
|
56
|
+
#endif
|
57
|
+
},
|
58
|
+
0, 0,
|
59
|
+
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
60
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
61
|
+
#endif
|
62
|
+
};
|
33
63
|
|
34
|
-
/* :nodoc: */
|
35
64
|
static void
|
36
65
|
relink_namespace(xmlNodePtr reparented)
|
37
66
|
{
|
38
67
|
xmlNodePtr child;
|
68
|
+
xmlAttrPtr attr;
|
39
69
|
|
40
70
|
if (reparented->type != XML_ATTRIBUTE_NODE &&
|
41
71
|
reparented->type != XML_ELEMENT_NODE) { return; }
|
@@ -69,7 +99,9 @@ relink_namespace(xmlNodePtr reparented)
|
|
69
99
|
if (reparented->type != XML_ELEMENT_NODE || !reparented->parent) { return; }
|
70
100
|
|
71
101
|
/* Make sure that our reparented node has the correct namespaces */
|
72
|
-
if (!reparented->ns &&
|
102
|
+
if (!reparented->ns &&
|
103
|
+
(reparented->doc != (xmlDocPtr)reparented->parent) &&
|
104
|
+
(rb_iv_get(DOC_RUBY_OBJECT(reparented->doc), "@namespace_inheritance") == Qtrue)) {
|
73
105
|
xmlSetNs(reparented, reparented->parent->ns);
|
74
106
|
}
|
75
107
|
|
@@ -132,15 +164,17 @@ relink_namespace(xmlNodePtr reparented)
|
|
132
164
|
}
|
133
165
|
|
134
166
|
if (reparented->type == XML_ELEMENT_NODE) {
|
135
|
-
|
136
|
-
while (NULL !=
|
137
|
-
relink_namespace(
|
138
|
-
|
167
|
+
attr = reparented->properties;
|
168
|
+
while (NULL != attr) {
|
169
|
+
relink_namespace((xmlNodePtr)attr);
|
170
|
+
attr = attr->next;
|
139
171
|
}
|
140
172
|
}
|
141
173
|
}
|
142
174
|
|
143
|
-
|
175
|
+
|
176
|
+
/* internal function meant to wrap xmlReplaceNode
|
177
|
+
and fix some issues we have with libxml2 merging nodes */
|
144
178
|
static xmlNodePtr
|
145
179
|
xmlReplaceNodeWrapper(xmlNodePtr pivot, xmlNodePtr new_node)
|
146
180
|
{
|
@@ -165,12 +199,23 @@ xmlReplaceNodeWrapper(xmlNodePtr pivot, xmlNodePtr new_node)
|
|
165
199
|
return retval ;
|
166
200
|
}
|
167
201
|
|
168
|
-
|
202
|
+
|
203
|
+
static void
|
204
|
+
raise_if_ancestor_of_self(xmlNodePtr self)
|
205
|
+
{
|
206
|
+
for (xmlNodePtr ancestor = self->parent ; ancestor ; ancestor = ancestor->parent) {
|
207
|
+
if (self == ancestor) {
|
208
|
+
rb_raise(rb_eRuntimeError, "cycle detected: node '%s' is an ancestor of itself", self->name);
|
209
|
+
}
|
210
|
+
}
|
211
|
+
}
|
212
|
+
|
213
|
+
|
169
214
|
static VALUE
|
170
215
|
reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_reparentee_func prf)
|
171
216
|
{
|
172
217
|
VALUE reparented_obj ;
|
173
|
-
xmlNodePtr reparentee, pivot, reparented, next_text, new_next_text, parent ;
|
218
|
+
xmlNodePtr reparentee, original_reparentee, pivot, reparented, next_text, new_next_text, parent ;
|
174
219
|
int original_ns_prefix_is_default = 0 ;
|
175
220
|
|
176
221
|
if (!rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlNode)) {
|
@@ -180,8 +225,8 @@ reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_reparentee_func
|
|
180
225
|
rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node");
|
181
226
|
}
|
182
227
|
|
183
|
-
|
184
|
-
|
228
|
+
Noko_Node_Get_Struct(reparentee_obj, xmlNode, reparentee);
|
229
|
+
Noko_Node_Get_Struct(pivot_obj, xmlNode, pivot);
|
185
230
|
|
186
231
|
/*
|
187
232
|
* Check if nodes given are appropriate to have a parent-child
|
@@ -197,66 +242,66 @@ reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_reparentee_func
|
|
197
242
|
|
198
243
|
if (parent) {
|
199
244
|
switch (parent->type) {
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
245
|
+
case XML_DOCUMENT_NODE:
|
246
|
+
case XML_HTML_DOCUMENT_NODE:
|
247
|
+
switch (reparentee->type) {
|
248
|
+
case XML_ELEMENT_NODE:
|
249
|
+
case XML_PI_NODE:
|
250
|
+
case XML_COMMENT_NODE:
|
251
|
+
case XML_DOCUMENT_TYPE_NODE:
|
252
|
+
/*
|
253
|
+
* The DOM specification says no to adding text-like nodes
|
254
|
+
* directly to a document, but we allow it for compatibility.
|
255
|
+
*/
|
256
|
+
case XML_TEXT_NODE:
|
257
|
+
case XML_CDATA_SECTION_NODE:
|
258
|
+
case XML_ENTITY_REF_NODE:
|
259
|
+
goto ok;
|
260
|
+
default:
|
261
|
+
break;
|
262
|
+
}
|
216
263
|
break;
|
217
|
-
|
218
|
-
break;
|
219
|
-
case XML_DOCUMENT_FRAG_NODE:
|
220
|
-
case XML_ENTITY_REF_NODE:
|
221
|
-
case XML_ELEMENT_NODE:
|
222
|
-
switch (reparentee->type) {
|
223
|
-
case XML_ELEMENT_NODE:
|
224
|
-
case XML_PI_NODE:
|
225
|
-
case XML_COMMENT_NODE:
|
226
|
-
case XML_TEXT_NODE:
|
227
|
-
case XML_CDATA_SECTION_NODE:
|
264
|
+
case XML_DOCUMENT_FRAG_NODE:
|
228
265
|
case XML_ENTITY_REF_NODE:
|
229
|
-
|
230
|
-
|
266
|
+
case XML_ELEMENT_NODE:
|
267
|
+
switch (reparentee->type) {
|
268
|
+
case XML_ELEMENT_NODE:
|
269
|
+
case XML_PI_NODE:
|
270
|
+
case XML_COMMENT_NODE:
|
271
|
+
case XML_TEXT_NODE:
|
272
|
+
case XML_CDATA_SECTION_NODE:
|
273
|
+
case XML_ENTITY_REF_NODE:
|
274
|
+
goto ok;
|
275
|
+
default:
|
276
|
+
break;
|
277
|
+
}
|
278
|
+
break;
|
279
|
+
case XML_ATTRIBUTE_NODE:
|
280
|
+
switch (reparentee->type) {
|
281
|
+
case XML_TEXT_NODE:
|
282
|
+
case XML_ENTITY_REF_NODE:
|
283
|
+
goto ok;
|
284
|
+
default:
|
285
|
+
break;
|
286
|
+
}
|
231
287
|
break;
|
232
|
-
}
|
233
|
-
break;
|
234
|
-
case XML_ATTRIBUTE_NODE:
|
235
|
-
switch (reparentee->type) {
|
236
288
|
case XML_TEXT_NODE:
|
237
|
-
|
238
|
-
|
289
|
+
/*
|
290
|
+
* xmlAddChild() breaks the DOM specification in that it allows
|
291
|
+
* adding a text node to another, in which case text nodes are
|
292
|
+
* coalesced, but since our JRuby version does not support such
|
293
|
+
* operation, we should inhibit it.
|
294
|
+
*/
|
295
|
+
break;
|
239
296
|
default:
|
240
297
|
break;
|
241
|
-
}
|
242
|
-
break;
|
243
|
-
case XML_TEXT_NODE:
|
244
|
-
/*
|
245
|
-
* xmlAddChild() breaks the DOM specification in that it allows
|
246
|
-
* adding a text node to another, in which case text nodes are
|
247
|
-
* coalesced, but since our JRuby version does not support such
|
248
|
-
* operation, we should inhibit it.
|
249
|
-
*/
|
250
|
-
break;
|
251
|
-
default:
|
252
|
-
break;
|
253
298
|
}
|
254
299
|
|
255
300
|
rb_raise(rb_eArgError, "cannot reparent %s there", rb_obj_classname(reparentee_obj));
|
256
301
|
}
|
257
302
|
|
258
303
|
ok:
|
259
|
-
|
304
|
+
original_reparentee = reparentee;
|
260
305
|
|
261
306
|
if (reparentee->doc != pivot->doc || reparentee->type == XML_TEXT_NODE) {
|
262
307
|
/*
|
@@ -308,11 +353,13 @@ ok:
|
|
308
353
|
* issue #391, where new node's prefix may become the string "default"
|
309
354
|
* see libxml2 tree.c xmlNewReconciliedNs which implements this behavior.
|
310
355
|
*/
|
311
|
-
xmlFree((
|
356
|
+
xmlFree(DISCARD_CONST_QUAL_XMLCHAR(reparentee->ns->prefix));
|
312
357
|
reparentee->ns->prefix = NULL;
|
313
358
|
}
|
314
359
|
}
|
315
360
|
|
361
|
+
xmlUnlinkNode(original_reparentee);
|
362
|
+
|
316
363
|
if (prf != xmlAddPrevSibling && prf != xmlAddNextSibling
|
317
364
|
&& reparentee->type == XML_TEXT_NODE && pivot->next && pivot->next->type == XML_TEXT_NODE) {
|
318
365
|
/*
|
@@ -352,49 +399,421 @@ ok:
|
|
352
399
|
* adjacent text nodes.
|
353
400
|
*/
|
354
401
|
DATA_PTR(reparentee_obj) = reparented ;
|
355
|
-
|
356
|
-
relink_namespace(reparented);
|
357
|
-
|
358
402
|
reparented_obj = noko_xml_node_wrap(Qnil, reparented);
|
359
403
|
|
360
404
|
rb_funcall(reparented_obj, id_decorate_bang, 0);
|
361
405
|
|
406
|
+
/* if we've created a cycle, raise an exception */
|
407
|
+
raise_if_ancestor_of_self(reparented);
|
408
|
+
|
409
|
+
relink_namespace(reparented);
|
410
|
+
|
362
411
|
return reparented_obj ;
|
363
412
|
}
|
364
413
|
|
414
|
+
// :startdoc:
|
365
415
|
|
366
416
|
/*
|
367
|
-
* call-seq:
|
368
|
-
*
|
417
|
+
* :call-seq:
|
418
|
+
* add_namespace_definition(prefix, href) → Nokogiri::XML::Namespace
|
419
|
+
* add_namespace(prefix, href) → Nokogiri::XML::Namespace
|
420
|
+
*
|
421
|
+
* :category: Manipulating Document Structure
|
422
|
+
*
|
423
|
+
* Adds a namespace definition to this node with +prefix+ using +href+ value, as if this node had
|
424
|
+
* included an attribute "xmlns:prefix=href".
|
425
|
+
*
|
426
|
+
* A default namespace definition for this node can be added by passing +nil+ for +prefix+.
|
427
|
+
*
|
428
|
+
* [Parameters]
|
429
|
+
* - +prefix+ (String, +nil+) An {XML Name}[https://www.w3.org/TR/xml-names/#ns-decl]
|
430
|
+
* - +href+ (String) The {URI reference}[https://www.w3.org/TR/xml-names/#sec-namespaces]
|
431
|
+
*
|
432
|
+
* [Returns] The new Nokogiri::XML::Namespace
|
433
|
+
*
|
434
|
+
* *Example:* adding a non-default namespace definition
|
435
|
+
*
|
436
|
+
* doc = Nokogiri::XML("<store><inventory></inventory></store>")
|
437
|
+
* inventory = doc.at_css("inventory")
|
438
|
+
* inventory.add_namespace_definition("automobile", "http://alices-autos.com/")
|
439
|
+
* inventory.add_namespace_definition("bicycle", "http://bobs-bikes.com/")
|
440
|
+
* inventory.add_child("<automobile:tire>Michelin model XGV, size 75R</automobile:tire>")
|
441
|
+
* doc.to_xml
|
442
|
+
* # => "<?xml version=\"1.0\"?>\n" +
|
443
|
+
* # "<store>\n" +
|
444
|
+
* # " <inventory xmlns:automobile=\"http://alices-autos.com/\" xmlns:bicycle=\"http://bobs-bikes.com/\">\n" +
|
445
|
+
* # " <automobile:tire>Michelin model XGV, size 75R</automobile:tire>\n" +
|
446
|
+
* # " </inventory>\n" +
|
447
|
+
* # "</store>\n"
|
448
|
+
*
|
449
|
+
* *Example:* adding a default namespace definition
|
450
|
+
*
|
451
|
+
* doc = Nokogiri::XML("<store><inventory><tire>Michelin model XGV, size 75R</tire></inventory></store>")
|
452
|
+
* doc.at_css("tire").add_namespace_definition(nil, "http://bobs-bikes.com/")
|
453
|
+
* doc.to_xml
|
454
|
+
* # => "<?xml version=\"1.0\"?>\n" +
|
455
|
+
* # "<store>\n" +
|
456
|
+
* # " <inventory>\n" +
|
457
|
+
* # " <tire xmlns=\"http://bobs-bikes.com/\">Michelin model XGV, size 75R</tire>\n" +
|
458
|
+
* # " </inventory>\n" +
|
459
|
+
* # "</store>\n"
|
369
460
|
*
|
370
|
-
* Get the document for this Node
|
371
461
|
*/
|
372
462
|
static VALUE
|
373
|
-
|
463
|
+
rb_xml_node_add_namespace_definition(VALUE rb_node, VALUE rb_prefix, VALUE rb_href)
|
464
|
+
{
|
465
|
+
xmlNodePtr c_node, element;
|
466
|
+
xmlNsPtr c_namespace;
|
467
|
+
const xmlChar *c_prefix = (const xmlChar *)(NIL_P(rb_prefix) ? NULL : StringValueCStr(rb_prefix));
|
468
|
+
|
469
|
+
Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
|
470
|
+
element = c_node ;
|
471
|
+
|
472
|
+
c_namespace = xmlSearchNs(c_node->doc, c_node, c_prefix);
|
473
|
+
|
474
|
+
if (!c_namespace) {
|
475
|
+
if (c_node->type != XML_ELEMENT_NODE) {
|
476
|
+
element = c_node->parent;
|
477
|
+
}
|
478
|
+
c_namespace = xmlNewNs(element, (const xmlChar *)StringValueCStr(rb_href), c_prefix);
|
479
|
+
}
|
480
|
+
|
481
|
+
if (!c_namespace) {
|
482
|
+
return Qnil ;
|
483
|
+
}
|
484
|
+
|
485
|
+
if (NIL_P(rb_prefix) || c_node != element) {
|
486
|
+
xmlSetNs(c_node, c_namespace);
|
487
|
+
}
|
488
|
+
|
489
|
+
return noko_xml_namespace_wrap(c_namespace, c_node->doc);
|
490
|
+
}
|
491
|
+
|
492
|
+
|
493
|
+
/*
|
494
|
+
* :call-seq: attribute(name) → Nokogiri::XML::Attr
|
495
|
+
*
|
496
|
+
* :category: Working With Node Attributes
|
497
|
+
*
|
498
|
+
* [Returns] Attribute (Nokogiri::XML::Attr) belonging to this node with name +name+.
|
499
|
+
*
|
500
|
+
* ⚠ Note that attribute namespaces are ignored and only the simple (non-namespace-prefixed) name is
|
501
|
+
* used to find a matching attribute. In case of a simple name collision, only one of the matching
|
502
|
+
* attributes will be returned. In this case, you will need to use #attribute_with_ns.
|
503
|
+
*
|
504
|
+
* *Example:*
|
505
|
+
*
|
506
|
+
* doc = Nokogiri::XML("<root><child size='large' class='big wide tall'/></root>")
|
507
|
+
* child = doc.at_css("child")
|
508
|
+
* child.attribute("size") # => #<Nokogiri::XML::Attr:0x550 name="size" value="large">
|
509
|
+
* child.attribute("class") # => #<Nokogiri::XML::Attr:0x564 name="class" value="big wide tall">
|
510
|
+
*
|
511
|
+
* *Example* showing that namespaced attributes will not be returned:
|
512
|
+
*
|
513
|
+
* ⚠ Note that only one of the two matching attributes is returned.
|
514
|
+
*
|
515
|
+
* doc = Nokogiri::XML(<<~EOF)
|
516
|
+
* <root xmlns:width='http://example.com/widths'
|
517
|
+
* xmlns:height='http://example.com/heights'>
|
518
|
+
* <child width:size='broad' height:size='tall'/>
|
519
|
+
* </root>
|
520
|
+
* EOF
|
521
|
+
* doc.at_css("child").attribute("size")
|
522
|
+
* # => #(Attr:0x550 {
|
523
|
+
* # name = "size",
|
524
|
+
* # namespace = #(Namespace:0x564 {
|
525
|
+
* # prefix = "width",
|
526
|
+
* # href = "http://example.com/widths"
|
527
|
+
* # }),
|
528
|
+
* # value = "broad"
|
529
|
+
* # })
|
530
|
+
*/
|
531
|
+
static VALUE
|
532
|
+
rb_xml_node_attribute(VALUE self, VALUE name)
|
374
533
|
{
|
375
534
|
xmlNodePtr node;
|
376
|
-
|
535
|
+
xmlAttrPtr prop;
|
536
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
537
|
+
prop = xmlHasProp(node, (xmlChar *)StringValueCStr(name));
|
538
|
+
|
539
|
+
if (! prop) { return Qnil; }
|
540
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)prop);
|
541
|
+
}
|
542
|
+
|
543
|
+
|
544
|
+
/*
|
545
|
+
* :call-seq: attribute_nodes() → Array<Nokogiri::XML::Attr>
|
546
|
+
*
|
547
|
+
* :category: Working With Node Attributes
|
548
|
+
*
|
549
|
+
* [Returns] Attributes (an Array of Nokogiri::XML::Attr) belonging to this node.
|
550
|
+
*
|
551
|
+
* Note that this is the preferred alternative to #attributes when the simple
|
552
|
+
* (non-namespace-prefixed) attribute names may collide.
|
553
|
+
*
|
554
|
+
* *Example:*
|
555
|
+
*
|
556
|
+
* Contrast this with the colliding-name example from #attributes.
|
557
|
+
*
|
558
|
+
* doc = Nokogiri::XML(<<~EOF)
|
559
|
+
* <root xmlns:width='http://example.com/widths'
|
560
|
+
* xmlns:height='http://example.com/heights'>
|
561
|
+
* <child width:size='broad' height:size='tall'/>
|
562
|
+
* </root>
|
563
|
+
* EOF
|
564
|
+
* doc.at_css("child").attribute_nodes
|
565
|
+
* # => [#(Attr:0x550 {
|
566
|
+
* # name = "size",
|
567
|
+
* # namespace = #(Namespace:0x564 {
|
568
|
+
* # prefix = "width",
|
569
|
+
* # href = "http://example.com/widths"
|
570
|
+
* # }),
|
571
|
+
* # value = "broad"
|
572
|
+
* # }),
|
573
|
+
* # #(Attr:0x578 {
|
574
|
+
* # name = "size",
|
575
|
+
* # namespace = #(Namespace:0x58c {
|
576
|
+
* # prefix = "height",
|
577
|
+
* # href = "http://example.com/heights"
|
578
|
+
* # }),
|
579
|
+
* # value = "tall"
|
580
|
+
* # })]
|
581
|
+
*/
|
582
|
+
static VALUE
|
583
|
+
rb_xml_node_attribute_nodes(VALUE rb_node)
|
584
|
+
{
|
585
|
+
xmlNodePtr c_node;
|
586
|
+
|
587
|
+
Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
|
588
|
+
|
589
|
+
return noko_xml_node_attrs(c_node);
|
590
|
+
}
|
591
|
+
|
592
|
+
|
593
|
+
/*
|
594
|
+
* :call-seq: attribute_with_ns(name, namespace) → Nokogiri::XML::Attr
|
595
|
+
*
|
596
|
+
* :category: Working With Node Attributes
|
597
|
+
*
|
598
|
+
* [Returns]
|
599
|
+
* Attribute (Nokogiri::XML::Attr) belonging to this node with matching +name+ and +namespace+.
|
600
|
+
*
|
601
|
+
* [Parameters]
|
602
|
+
* - +name+ (String): the simple (non-namespace-prefixed) name of the attribute
|
603
|
+
* - +namespace+ (String): the URI of the attribute's namespace
|
604
|
+
*
|
605
|
+
* See related: #attribute
|
606
|
+
*
|
607
|
+
* *Example:*
|
608
|
+
*
|
609
|
+
* doc = Nokogiri::XML(<<~EOF)
|
610
|
+
* <root xmlns:width='http://example.com/widths'
|
611
|
+
* xmlns:height='http://example.com/heights'>
|
612
|
+
* <child width:size='broad' height:size='tall'/>
|
613
|
+
* </root>
|
614
|
+
* EOF
|
615
|
+
* doc.at_css("child").attribute_with_ns("size", "http://example.com/widths")
|
616
|
+
* # => #(Attr:0x550 {
|
617
|
+
* # name = "size",
|
618
|
+
* # namespace = #(Namespace:0x564 {
|
619
|
+
* # prefix = "width",
|
620
|
+
* # href = "http://example.com/widths"
|
621
|
+
* # }),
|
622
|
+
* # value = "broad"
|
623
|
+
* # })
|
624
|
+
* doc.at_css("child").attribute_with_ns("size", "http://example.com/heights")
|
625
|
+
* # => #(Attr:0x578 {
|
626
|
+
* # name = "size",
|
627
|
+
* # namespace = #(Namespace:0x58c {
|
628
|
+
* # prefix = "height",
|
629
|
+
* # href = "http://example.com/heights"
|
630
|
+
* # }),
|
631
|
+
* # value = "tall"
|
632
|
+
* # })
|
633
|
+
*/
|
634
|
+
static VALUE
|
635
|
+
rb_xml_node_attribute_with_ns(VALUE self, VALUE name, VALUE namespace)
|
636
|
+
{
|
637
|
+
xmlNodePtr node;
|
638
|
+
xmlAttrPtr prop;
|
639
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
640
|
+
prop = xmlHasNsProp(node, (xmlChar *)StringValueCStr(name),
|
641
|
+
NIL_P(namespace) ? NULL : (xmlChar *)StringValueCStr(namespace));
|
642
|
+
|
643
|
+
if (! prop) { return Qnil; }
|
644
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)prop);
|
645
|
+
}
|
646
|
+
|
647
|
+
|
648
|
+
|
649
|
+
/*
|
650
|
+
* call-seq: blank? → Boolean
|
651
|
+
*
|
652
|
+
* [Returns] +true+ if the node is an empty or whitespace-only text or cdata node, else +false+.
|
653
|
+
*
|
654
|
+
* *Example:*
|
655
|
+
*
|
656
|
+
* Nokogiri("<root><child/></root>").root.child.blank? # => false
|
657
|
+
* Nokogiri("<root>\t \n</root>").root.child.blank? # => true
|
658
|
+
* Nokogiri("<root><![CDATA[\t \n]]></root>").root.child.blank? # => true
|
659
|
+
* Nokogiri("<root>not-blank</root>").root.child
|
660
|
+
* .tap { |n| n.content = "" }.blank # => true
|
661
|
+
*/
|
662
|
+
static VALUE
|
663
|
+
rb_xml_node_blank_eh(VALUE self)
|
664
|
+
{
|
665
|
+
xmlNodePtr node;
|
666
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
667
|
+
return (1 == xmlIsBlankNode(node)) ? Qtrue : Qfalse ;
|
668
|
+
}
|
669
|
+
|
670
|
+
|
671
|
+
/*
|
672
|
+
* :call-seq: child() → Nokogiri::XML::Node
|
673
|
+
*
|
674
|
+
* :category: Traversing Document Structure
|
675
|
+
*
|
676
|
+
* [Returns] First of this node's children, or +nil+ if there are no children
|
677
|
+
*
|
678
|
+
* This is a convenience method and is equivalent to:
|
679
|
+
*
|
680
|
+
* node.children.first
|
681
|
+
*
|
682
|
+
* See related: #children
|
683
|
+
*/
|
684
|
+
static VALUE
|
685
|
+
rb_xml_node_child(VALUE self)
|
686
|
+
{
|
687
|
+
xmlNodePtr node, child;
|
688
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
689
|
+
|
690
|
+
child = node->children;
|
691
|
+
if (!child) { return Qnil; }
|
692
|
+
|
693
|
+
return noko_xml_node_wrap(Qnil, child);
|
694
|
+
}
|
695
|
+
|
696
|
+
|
697
|
+
/*
|
698
|
+
* :call-seq: children() → Nokogiri::XML::NodeSet
|
699
|
+
*
|
700
|
+
* :category: Traversing Document Structure
|
701
|
+
*
|
702
|
+
* [Returns] Nokogiri::XML::NodeSet containing this node's children.
|
703
|
+
*/
|
704
|
+
static VALUE
|
705
|
+
rb_xml_node_children(VALUE self)
|
706
|
+
{
|
707
|
+
xmlNodePtr node;
|
708
|
+
xmlNodePtr child;
|
709
|
+
xmlNodeSetPtr set;
|
710
|
+
VALUE document;
|
711
|
+
VALUE node_set;
|
712
|
+
|
713
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
714
|
+
|
715
|
+
child = node->children;
|
716
|
+
set = xmlXPathNodeSetCreate(child);
|
717
|
+
|
718
|
+
document = DOC_RUBY_OBJECT(node->doc);
|
719
|
+
|
720
|
+
if (!child) { return noko_xml_node_set_wrap(set, document); }
|
721
|
+
|
722
|
+
child = child->next;
|
723
|
+
while (NULL != child) {
|
724
|
+
xmlXPathNodeSetAddUnique(set, child);
|
725
|
+
child = child->next;
|
726
|
+
}
|
727
|
+
|
728
|
+
node_set = noko_xml_node_set_wrap(set, document);
|
729
|
+
|
730
|
+
return node_set;
|
731
|
+
}
|
732
|
+
|
733
|
+
|
734
|
+
/*
|
735
|
+
* :call-seq:
|
736
|
+
* content() → String
|
737
|
+
* inner_text() → String
|
738
|
+
* text() → String
|
739
|
+
* to_str() → String
|
740
|
+
*
|
741
|
+
* [Returns]
|
742
|
+
* Contents of all the text nodes in this node's subtree, concatenated together into a single
|
743
|
+
* String.
|
744
|
+
*
|
745
|
+
* ⚠ Note that entities will _always_ be expanded in the returned String.
|
746
|
+
*
|
747
|
+
* See related: #inner_html
|
748
|
+
*
|
749
|
+
* *Example* of how entities are handled:
|
750
|
+
*
|
751
|
+
* Note that <tt><</tt> becomes <tt><</tt> in the returned String.
|
752
|
+
*
|
753
|
+
* doc = Nokogiri::XML.fragment("<child>a < b</child>")
|
754
|
+
* doc.at_css("child").content
|
755
|
+
* # => "a < b"
|
756
|
+
*
|
757
|
+
* *Example* of how a subtree is handled:
|
758
|
+
*
|
759
|
+
* Note that the <tt><span></tt> tags are omitted and only the text node contents are returned,
|
760
|
+
* concatenated into a single string.
|
761
|
+
*
|
762
|
+
* doc = Nokogiri::XML.fragment("<child><span>first</span> <span>second</span></child>")
|
763
|
+
* doc.at_css("child").content
|
764
|
+
* # => "first second"
|
765
|
+
*/
|
766
|
+
static VALUE
|
767
|
+
rb_xml_node_content(VALUE self)
|
768
|
+
{
|
769
|
+
xmlNodePtr node;
|
770
|
+
xmlChar *content;
|
771
|
+
|
772
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
773
|
+
|
774
|
+
content = xmlNodeGetContent(node);
|
775
|
+
if (content) {
|
776
|
+
VALUE rval = NOKOGIRI_STR_NEW2(content);
|
777
|
+
xmlFree(content);
|
778
|
+
return rval;
|
779
|
+
}
|
780
|
+
return Qnil;
|
781
|
+
}
|
782
|
+
|
783
|
+
|
784
|
+
/*
|
785
|
+
* :call-seq: document() → Nokogiri::XML::Document
|
786
|
+
*
|
787
|
+
* :category: Traversing Document Structure
|
788
|
+
*
|
789
|
+
* [Returns] Parent Nokogiri::XML::Document for this node
|
790
|
+
*/
|
791
|
+
static VALUE
|
792
|
+
rb_xml_node_document(VALUE self)
|
793
|
+
{
|
794
|
+
xmlNodePtr node;
|
795
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
377
796
|
return DOC_RUBY_OBJECT(node->doc);
|
378
797
|
}
|
379
798
|
|
380
799
|
/*
|
381
|
-
* call-seq:
|
382
|
-
* pointer_id
|
800
|
+
* :call-seq: pointer_id() → Integer
|
383
801
|
*
|
384
|
-
*
|
802
|
+
* [Returns]
|
803
|
+
* A unique id for this node based on the internal memory structures. This method is used by #==
|
804
|
+
* to determine node identity.
|
385
805
|
*/
|
386
806
|
static VALUE
|
387
|
-
|
807
|
+
rb_xml_node_pointer_id(VALUE self)
|
388
808
|
{
|
389
809
|
xmlNodePtr node;
|
390
|
-
|
810
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
391
811
|
|
392
812
|
return INT2NUM((long)(node));
|
393
813
|
}
|
394
814
|
|
395
815
|
/*
|
396
|
-
* call-seq:
|
397
|
-
* encode_special_chars(string)
|
816
|
+
* :call-seq: encode_special_chars(string) → String
|
398
817
|
*
|
399
818
|
* Encode any special characters in +string+
|
400
819
|
*/
|
@@ -405,7 +824,7 @@ encode_special_chars(VALUE self, VALUE string)
|
|
405
824
|
xmlChar *encoded;
|
406
825
|
VALUE encoded_str;
|
407
826
|
|
408
|
-
|
827
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
409
828
|
encoded = xmlEncodeSpecialChars(
|
410
829
|
node->doc,
|
411
830
|
(const xmlChar *)StringValueCStr(string)
|
@@ -418,8 +837,8 @@ encode_special_chars(VALUE self, VALUE string)
|
|
418
837
|
}
|
419
838
|
|
420
839
|
/*
|
421
|
-
* call-seq:
|
422
|
-
*
|
840
|
+
* :call-seq:
|
841
|
+
* create_internal_subset(name, external_id, system_id)
|
423
842
|
*
|
424
843
|
* Create the internal subset of a document.
|
425
844
|
*
|
@@ -436,7 +855,7 @@ create_internal_subset(VALUE self, VALUE name, VALUE external_id, VALUE system_i
|
|
436
855
|
xmlDocPtr doc;
|
437
856
|
xmlDtdPtr dtd;
|
438
857
|
|
439
|
-
|
858
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
440
859
|
|
441
860
|
doc = node->doc;
|
442
861
|
|
@@ -457,8 +876,8 @@ create_internal_subset(VALUE self, VALUE name, VALUE external_id, VALUE system_i
|
|
457
876
|
}
|
458
877
|
|
459
878
|
/*
|
460
|
-
* call-seq:
|
461
|
-
*
|
879
|
+
* :call-seq:
|
880
|
+
* create_external_subset(name, external_id, system_id)
|
462
881
|
*
|
463
882
|
* Create an external subset
|
464
883
|
*/
|
@@ -469,7 +888,7 @@ create_external_subset(VALUE self, VALUE name, VALUE external_id, VALUE system_i
|
|
469
888
|
xmlDocPtr doc;
|
470
889
|
xmlDtdPtr dtd;
|
471
890
|
|
472
|
-
|
891
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
473
892
|
|
474
893
|
doc = node->doc;
|
475
894
|
|
@@ -490,8 +909,8 @@ create_external_subset(VALUE self, VALUE name, VALUE external_id, VALUE system_i
|
|
490
909
|
}
|
491
910
|
|
492
911
|
/*
|
493
|
-
* call-seq:
|
494
|
-
*
|
912
|
+
* :call-seq:
|
913
|
+
* external_subset()
|
495
914
|
*
|
496
915
|
* Get the external subset
|
497
916
|
*/
|
@@ -502,7 +921,7 @@ external_subset(VALUE self)
|
|
502
921
|
xmlDocPtr doc;
|
503
922
|
xmlDtdPtr dtd;
|
504
923
|
|
505
|
-
|
924
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
506
925
|
|
507
926
|
if (!node->doc) { return Qnil; }
|
508
927
|
|
@@ -515,8 +934,8 @@ external_subset(VALUE self)
|
|
515
934
|
}
|
516
935
|
|
517
936
|
/*
|
518
|
-
* call-seq:
|
519
|
-
*
|
937
|
+
* :call-seq:
|
938
|
+
* internal_subset()
|
520
939
|
*
|
521
940
|
* Get the internal subset
|
522
941
|
*/
|
@@ -527,7 +946,7 @@ internal_subset(VALUE self)
|
|
527
946
|
xmlDocPtr doc;
|
528
947
|
xmlDtdPtr dtd;
|
529
948
|
|
530
|
-
|
949
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
531
950
|
|
532
951
|
if (!node->doc) { return Qnil; }
|
533
952
|
|
@@ -540,16 +959,19 @@ internal_subset(VALUE self)
|
|
540
959
|
}
|
541
960
|
|
542
961
|
/*
|
543
|
-
* call-seq:
|
544
|
-
*
|
545
|
-
*
|
546
|
-
*
|
962
|
+
* :call-seq:
|
963
|
+
* dup → Nokogiri::XML::Node
|
964
|
+
* dup(depth) → Nokogiri::XML::Node
|
965
|
+
* dup(depth, new_parent_doc) → Nokogiri::XML::Node
|
547
966
|
*
|
548
967
|
* Copy this node.
|
549
|
-
*
|
550
|
-
*
|
551
|
-
*
|
552
|
-
*
|
968
|
+
*
|
969
|
+
* [Parameters]
|
970
|
+
* - +depth+ 0 is a shallow copy, 1 (the default) is a deep copy.
|
971
|
+
* - +new_parent_doc+
|
972
|
+
* The new node's parent Document. Defaults to the this node's document.
|
973
|
+
*
|
974
|
+
* [Returns] The new Nokgiri::XML::Node
|
553
975
|
*/
|
554
976
|
static VALUE
|
555
977
|
duplicate_node(int argc, VALUE *argv, VALUE self)
|
@@ -560,7 +982,7 @@ duplicate_node(int argc, VALUE *argv, VALUE self)
|
|
560
982
|
xmlDocPtr new_parent_doc;
|
561
983
|
xmlNodePtr node, dup;
|
562
984
|
|
563
|
-
|
985
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
564
986
|
|
565
987
|
n_args = rb_scan_args(argc, argv, "02", &r_level, &r_new_parent_doc);
|
566
988
|
|
@@ -584,35 +1006,22 @@ duplicate_node(int argc, VALUE *argv, VALUE self)
|
|
584
1006
|
}
|
585
1007
|
|
586
1008
|
/*
|
587
|
-
* call-seq:
|
588
|
-
*
|
589
|
-
*
|
590
|
-
* Unlink this node from its current context.
|
591
|
-
*/
|
592
|
-
static VALUE
|
593
|
-
unlink_node(VALUE self)
|
594
|
-
{
|
595
|
-
xmlNodePtr node;
|
596
|
-
Data_Get_Struct(self, xmlNode, node);
|
597
|
-
xmlUnlinkNode(node);
|
598
|
-
noko_xml_document_pin_node(node);
|
599
|
-
return self;
|
600
|
-
}
|
601
|
-
|
602
|
-
/*
|
603
|
-
* call-seq:
|
604
|
-
* blank?
|
1009
|
+
* :call-seq:
|
1010
|
+
* unlink() → self
|
605
1011
|
*
|
606
|
-
*
|
1012
|
+
* Unlink this node from its current context.
|
607
1013
|
*/
|
608
1014
|
static VALUE
|
609
|
-
|
1015
|
+
unlink_node(VALUE self)
|
610
1016
|
{
|
611
1017
|
xmlNodePtr node;
|
612
|
-
|
613
|
-
|
1018
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1019
|
+
xmlUnlinkNode(node);
|
1020
|
+
noko_xml_document_pin_node(node);
|
1021
|
+
return self;
|
614
1022
|
}
|
615
1023
|
|
1024
|
+
|
616
1025
|
/*
|
617
1026
|
* call-seq:
|
618
1027
|
* next_sibling
|
@@ -623,7 +1032,7 @@ static VALUE
|
|
623
1032
|
next_sibling(VALUE self)
|
624
1033
|
{
|
625
1034
|
xmlNodePtr node, sibling;
|
626
|
-
|
1035
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
627
1036
|
|
628
1037
|
sibling = node->next;
|
629
1038
|
if (!sibling) { return Qnil; }
|
@@ -641,7 +1050,7 @@ static VALUE
|
|
641
1050
|
previous_sibling(VALUE self)
|
642
1051
|
{
|
643
1052
|
xmlNodePtr node, sibling;
|
644
|
-
|
1053
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
645
1054
|
|
646
1055
|
sibling = node->prev;
|
647
1056
|
if (!sibling) { return Qnil; }
|
@@ -659,7 +1068,7 @@ static VALUE
|
|
659
1068
|
next_element(VALUE self)
|
660
1069
|
{
|
661
1070
|
xmlNodePtr node, sibling;
|
662
|
-
|
1071
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
663
1072
|
|
664
1073
|
sibling = xmlNextElementSibling(node);
|
665
1074
|
if (!sibling) { return Qnil; }
|
@@ -677,7 +1086,7 @@ static VALUE
|
|
677
1086
|
previous_element(VALUE self)
|
678
1087
|
{
|
679
1088
|
xmlNodePtr node, sibling;
|
680
|
-
|
1089
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
681
1090
|
|
682
1091
|
/*
|
683
1092
|
* note that we don't use xmlPreviousElementSibling here because it's buggy pre-2.7.7.
|
@@ -699,60 +1108,34 @@ replace(VALUE self, VALUE new_node)
|
|
699
1108
|
VALUE reparent = reparent_node_with(self, new_node, xmlReplaceNodeWrapper);
|
700
1109
|
|
701
1110
|
xmlNodePtr pivot;
|
702
|
-
|
1111
|
+
Noko_Node_Get_Struct(self, xmlNode, pivot);
|
703
1112
|
noko_xml_document_pin_node(pivot);
|
704
1113
|
|
705
1114
|
return reparent;
|
706
1115
|
}
|
707
1116
|
|
708
1117
|
/*
|
709
|
-
* call-seq:
|
710
|
-
*
|
1118
|
+
* :call-seq:
|
1119
|
+
* element_children() → NodeSet
|
1120
|
+
* elements() → NodeSet
|
711
1121
|
*
|
712
|
-
*
|
713
|
-
|
714
|
-
|
715
|
-
children(VALUE self)
|
716
|
-
{
|
717
|
-
xmlNodePtr node;
|
718
|
-
xmlNodePtr child;
|
719
|
-
xmlNodeSetPtr set;
|
720
|
-
VALUE document;
|
721
|
-
VALUE node_set;
|
722
|
-
|
723
|
-
Data_Get_Struct(self, xmlNode, node);
|
724
|
-
|
725
|
-
child = node->children;
|
726
|
-
set = xmlXPathNodeSetCreate(child);
|
727
|
-
|
728
|
-
document = DOC_RUBY_OBJECT(node->doc);
|
729
|
-
|
730
|
-
if (!child) { return noko_xml_node_set_wrap(set, document); }
|
731
|
-
|
732
|
-
child = child->next;
|
733
|
-
while (NULL != child) {
|
734
|
-
xmlXPathNodeSetAddUnique(set, child);
|
735
|
-
child = child->next;
|
736
|
-
}
|
737
|
-
|
738
|
-
node_set = noko_xml_node_set_wrap(set, document);
|
739
|
-
|
740
|
-
return node_set;
|
741
|
-
}
|
742
|
-
|
743
|
-
/*
|
744
|
-
* call-seq:
|
745
|
-
* element_children
|
1122
|
+
* [Returns]
|
1123
|
+
* The node's child elements as a NodeSet. Only children that are elements will be returned, which
|
1124
|
+
* notably excludes Text nodes.
|
746
1125
|
*
|
747
|
-
*
|
748
|
-
* element nodes.
|
1126
|
+
* *Example:*
|
749
1127
|
*
|
750
|
-
*
|
1128
|
+
* Note that #children returns the Text node "hello" while #element_children does not.
|
751
1129
|
*
|
752
|
-
*
|
1130
|
+
* div = Nokogiri::HTML5("<div>hello<span>world</span>").at_css("div")
|
1131
|
+
* div.element_children
|
1132
|
+
* # => [#<Nokogiri::XML::Element:0x50 name="span" children=[#<Nokogiri::XML::Text:0x3c "world">]>]
|
1133
|
+
* div.children
|
1134
|
+
* # => [#<Nokogiri::XML::Text:0x64 "hello">,
|
1135
|
+
* # #<Nokogiri::XML::Element:0x50 name="span" children=[#<Nokogiri::XML::Text:0x3c "world">]>]
|
753
1136
|
*/
|
754
1137
|
static VALUE
|
755
|
-
|
1138
|
+
rb_xml_node_element_children(VALUE self)
|
756
1139
|
{
|
757
1140
|
xmlNodePtr node;
|
758
1141
|
xmlNodePtr child;
|
@@ -760,7 +1143,7 @@ element_children(VALUE self)
|
|
760
1143
|
VALUE document;
|
761
1144
|
VALUE node_set;
|
762
1145
|
|
763
|
-
|
1146
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
764
1147
|
|
765
1148
|
child = xmlFirstElementChild(node);
|
766
1149
|
set = xmlXPathNodeSetCreate(child);
|
@@ -781,38 +1164,25 @@ element_children(VALUE self)
|
|
781
1164
|
}
|
782
1165
|
|
783
1166
|
/*
|
784
|
-
* call-seq:
|
785
|
-
*
|
1167
|
+
* :call-seq:
|
1168
|
+
* first_element_child() → Node
|
786
1169
|
*
|
787
|
-
* Returns
|
788
|
-
*/
|
789
|
-
static VALUE
|
790
|
-
child(VALUE self)
|
791
|
-
{
|
792
|
-
xmlNodePtr node, child;
|
793
|
-
Data_Get_Struct(self, xmlNode, node);
|
794
|
-
|
795
|
-
child = node->children;
|
796
|
-
if (!child) { return Qnil; }
|
797
|
-
|
798
|
-
return noko_xml_node_wrap(Qnil, child);
|
799
|
-
}
|
800
|
-
|
801
|
-
/*
|
802
|
-
* call-seq:
|
803
|
-
* first_element_child
|
1170
|
+
* [Returns] The first child Node that is an element.
|
804
1171
|
*
|
805
|
-
*
|
1172
|
+
* *Example:*
|
806
1173
|
*
|
807
|
-
*
|
1174
|
+
* Note that the "hello" child, which is a Text node, is skipped and the <tt><span></tt> element is
|
1175
|
+
* returned.
|
808
1176
|
*
|
809
|
-
*
|
1177
|
+
* div = Nokogiri::HTML5("<div>hello<span>world</span>").at_css("div")
|
1178
|
+
* div.first_element_child
|
1179
|
+
* # => #(Element:0x3c { name = "span", children = [ #(Text "world")] })
|
810
1180
|
*/
|
811
1181
|
static VALUE
|
812
|
-
|
1182
|
+
rb_xml_node_first_element_child(VALUE self)
|
813
1183
|
{
|
814
1184
|
xmlNodePtr node, child;
|
815
|
-
|
1185
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
816
1186
|
|
817
1187
|
child = xmlFirstElementChild(node);
|
818
1188
|
if (!child) { return Qnil; }
|
@@ -821,20 +1191,25 @@ first_element_child(VALUE self)
|
|
821
1191
|
}
|
822
1192
|
|
823
1193
|
/*
|
824
|
-
* call-seq:
|
825
|
-
*
|
1194
|
+
* :call-seq:
|
1195
|
+
* last_element_child() → Node
|
826
1196
|
*
|
827
|
-
* Returns
|
1197
|
+
* [Returns] The last child Node that is an element.
|
828
1198
|
*
|
829
|
-
* Example
|
1199
|
+
* *Example:*
|
830
1200
|
*
|
831
|
-
*
|
1201
|
+
* Note that the "hello" child, which is a Text node, is skipped and the <tt><span>yes</span></tt>
|
1202
|
+
* element is returned.
|
1203
|
+
*
|
1204
|
+
* div = Nokogiri::HTML5("<div><span>no</span><span>yes</span>skip</div>").at_css("div")
|
1205
|
+
* div.last_element_child
|
1206
|
+
* # => #(Element:0x3c { name = "span", children = [ #(Text "yes")] })
|
832
1207
|
*/
|
833
1208
|
static VALUE
|
834
|
-
|
1209
|
+
rb_xml_node_last_element_child(VALUE self)
|
835
1210
|
{
|
836
1211
|
xmlNodePtr node, child;
|
837
|
-
|
1212
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
838
1213
|
|
839
1214
|
child = xmlLastElementChild(node);
|
840
1215
|
if (!child) { return Qnil; }
|
@@ -852,7 +1227,7 @@ static VALUE
|
|
852
1227
|
key_eh(VALUE self, VALUE attribute)
|
853
1228
|
{
|
854
1229
|
xmlNodePtr node;
|
855
|
-
|
1230
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
856
1231
|
if (xmlHasProp(node, (xmlChar *)StringValueCStr(attribute))) {
|
857
1232
|
return Qtrue;
|
858
1233
|
}
|
@@ -869,7 +1244,7 @@ static VALUE
|
|
869
1244
|
namespaced_key_eh(VALUE self, VALUE attribute, VALUE namespace)
|
870
1245
|
{
|
871
1246
|
xmlNodePtr node;
|
872
|
-
|
1247
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
873
1248
|
if (xmlHasNsProp(node, (xmlChar *)StringValueCStr(attribute),
|
874
1249
|
NIL_P(namespace) ? NULL : (xmlChar *)StringValueCStr(namespace))) {
|
875
1250
|
return Qtrue;
|
@@ -888,7 +1263,7 @@ set(VALUE self, VALUE property, VALUE value)
|
|
888
1263
|
{
|
889
1264
|
xmlNodePtr node, cur;
|
890
1265
|
xmlAttrPtr prop;
|
891
|
-
|
1266
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
892
1267
|
|
893
1268
|
/* If a matching attribute node already exists, then xmlSetProp will destroy
|
894
1269
|
* the existing node's children. However, if Nokogiri has a node object
|
@@ -933,10 +1308,10 @@ get(VALUE self, VALUE rattribute)
|
|
933
1308
|
|
934
1309
|
if (NIL_P(rattribute)) { return Qnil; }
|
935
1310
|
|
936
|
-
|
1311
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
937
1312
|
attribute = xmlCharStrdup(StringValueCStr(rattribute));
|
938
1313
|
|
939
|
-
colon = (
|
1314
|
+
colon = DISCARD_CONST_QUAL_XMLCHAR(xmlStrchr(attribute, (const xmlChar)':'));
|
940
1315
|
if (colon) {
|
941
1316
|
/* split the attribute string into separate prefix and name by
|
942
1317
|
* null-terminating the prefix at the colon */
|
@@ -975,7 +1350,7 @@ set_namespace(VALUE self, VALUE namespace)
|
|
975
1350
|
xmlNodePtr node;
|
976
1351
|
xmlNsPtr ns = NULL;
|
977
1352
|
|
978
|
-
|
1353
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
979
1354
|
|
980
1355
|
if (!NIL_P(namespace)) {
|
981
1356
|
Data_Get_Struct(namespace, xmlNs, ns);
|
@@ -987,70 +1362,32 @@ set_namespace(VALUE self, VALUE namespace)
|
|
987
1362
|
}
|
988
1363
|
|
989
1364
|
/*
|
990
|
-
* call-seq:
|
991
|
-
*
|
1365
|
+
* :call-seq:
|
1366
|
+
* namespace() → Namespace
|
992
1367
|
*
|
993
|
-
*
|
994
|
-
*/
|
995
|
-
static VALUE
|
996
|
-
attr(VALUE self, VALUE name)
|
997
|
-
{
|
998
|
-
xmlNodePtr node;
|
999
|
-
xmlAttrPtr prop;
|
1000
|
-
Data_Get_Struct(self, xmlNode, node);
|
1001
|
-
prop = xmlHasProp(node, (xmlChar *)StringValueCStr(name));
|
1002
|
-
|
1003
|
-
if (! prop) { return Qnil; }
|
1004
|
-
return noko_xml_node_wrap(Qnil, (xmlNodePtr)prop);
|
1005
|
-
}
|
1006
|
-
|
1007
|
-
/*
|
1008
|
-
* call-seq:
|
1009
|
-
* attribute_with_ns(name, namespace)
|
1368
|
+
* [Returns] The Namespace of the element or attribute node, or +nil+ if there is no namespace.
|
1010
1369
|
*
|
1011
|
-
*
|
1012
|
-
*/
|
1013
|
-
static VALUE
|
1014
|
-
attribute_with_ns(VALUE self, VALUE name, VALUE namespace)
|
1015
|
-
{
|
1016
|
-
xmlNodePtr node;
|
1017
|
-
xmlAttrPtr prop;
|
1018
|
-
Data_Get_Struct(self, xmlNode, node);
|
1019
|
-
prop = xmlHasNsProp(node, (xmlChar *)StringValueCStr(name),
|
1020
|
-
NIL_P(namespace) ? NULL : (xmlChar *)StringValueCStr(namespace));
|
1021
|
-
|
1022
|
-
if (! prop) { return Qnil; }
|
1023
|
-
return noko_xml_node_wrap(Qnil, (xmlNodePtr)prop);
|
1024
|
-
}
|
1025
|
-
|
1026
|
-
/*
|
1027
|
-
* @overload attribute_nodes()
|
1028
|
-
* Get the attributes for a Node
|
1029
|
-
* @return [Array<Nokogiri::XML::Attr>] containing the Node's attributes.
|
1030
|
-
*/
|
1031
|
-
static VALUE
|
1032
|
-
attribute_nodes(VALUE rb_node)
|
1033
|
-
{
|
1034
|
-
xmlNodePtr c_node;
|
1035
|
-
|
1036
|
-
Data_Get_Struct(rb_node, xmlNode, c_node);
|
1037
|
-
|
1038
|
-
return noko_xml_node_attrs(c_node);
|
1039
|
-
}
|
1040
|
-
|
1041
|
-
|
1042
|
-
/*
|
1043
|
-
* call-seq:
|
1044
|
-
* namespace()
|
1370
|
+
* *Example:*
|
1045
1371
|
*
|
1046
|
-
*
|
1047
|
-
*
|
1372
|
+
* doc = Nokogiri::XML(<<~EOF)
|
1373
|
+
* <root>
|
1374
|
+
* <first/>
|
1375
|
+
* <second xmlns="http://example.com/child"/>
|
1376
|
+
* <foo:third xmlns:foo="http://example.com/foo"/>
|
1377
|
+
* </root>
|
1378
|
+
* EOF
|
1379
|
+
* doc.at_xpath("//first").namespace
|
1380
|
+
* # => nil
|
1381
|
+
* doc.at_xpath("//xmlns:second", "xmlns" => "http://example.com/child").namespace
|
1382
|
+
* # => #(Namespace:0x3c { href = "http://example.com/child" })
|
1383
|
+
* doc.at_xpath("//foo:third", "foo" => "http://example.com/foo").namespace
|
1384
|
+
* # => #(Namespace:0x50 { prefix = "foo", href = "http://example.com/foo" })
|
1048
1385
|
*/
|
1049
1386
|
static VALUE
|
1050
|
-
|
1387
|
+
rb_xml_node_namespace(VALUE rb_node)
|
1051
1388
|
{
|
1052
1389
|
xmlNodePtr c_node ;
|
1053
|
-
|
1390
|
+
Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
|
1054
1391
|
|
1055
1392
|
if (c_node->ns) {
|
1056
1393
|
return noko_xml_namespace_wrap(c_node->ns, c_node->doc);
|
@@ -1060,10 +1397,32 @@ noko_xml_node_namespace(VALUE rb_node)
|
|
1060
1397
|
}
|
1061
1398
|
|
1062
1399
|
/*
|
1063
|
-
*
|
1064
|
-
*
|
1400
|
+
* :call-seq:
|
1401
|
+
* namespace_definitions() → Array<Nokogiri::XML::Namespace>
|
1402
|
+
*
|
1403
|
+
* [Returns]
|
1404
|
+
* Namespaces that are defined directly on this node, as an Array of Namespace objects. The array
|
1405
|
+
* will be empty if no namespaces are defined on this node.
|
1065
1406
|
*
|
1066
|
-
*
|
1407
|
+
* *Example:*
|
1408
|
+
*
|
1409
|
+
* doc = Nokogiri::XML(<<~EOF)
|
1410
|
+
* <root xmlns="http://example.com/root">
|
1411
|
+
* <first/>
|
1412
|
+
* <second xmlns="http://example.com/child" xmlns:unused="http://example.com/unused"/>
|
1413
|
+
* <foo:third xmlns:foo="http://example.com/foo"/>
|
1414
|
+
* </root>
|
1415
|
+
* EOF
|
1416
|
+
* doc.at_xpath("//root:first", "root" => "http://example.com/root").namespace_definitions
|
1417
|
+
* # => []
|
1418
|
+
* doc.at_xpath("//xmlns:second", "xmlns" => "http://example.com/child").namespace_definitions
|
1419
|
+
* # => [#(Namespace:0x3c { href = "http://example.com/child" }),
|
1420
|
+
* # #(Namespace:0x50 {
|
1421
|
+
* # prefix = "unused",
|
1422
|
+
* # href = "http://example.com/unused"
|
1423
|
+
* # })]
|
1424
|
+
* doc.at_xpath("//foo:third", "foo" => "http://example.com/foo").namespace_definitions
|
1425
|
+
* # => [#(Namespace:0x64 { prefix = "foo", href = "http://example.com/foo" })]
|
1067
1426
|
*/
|
1068
1427
|
static VALUE
|
1069
1428
|
namespace_definitions(VALUE rb_node)
|
@@ -1073,7 +1432,7 @@ namespace_definitions(VALUE rb_node)
|
|
1073
1432
|
xmlNsPtr c_namespace;
|
1074
1433
|
VALUE definitions = rb_ary_new();
|
1075
1434
|
|
1076
|
-
|
1435
|
+
Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
|
1077
1436
|
|
1078
1437
|
c_namespace = c_node->nsDef;
|
1079
1438
|
if (!c_namespace) {
|
@@ -1089,23 +1448,42 @@ namespace_definitions(VALUE rb_node)
|
|
1089
1448
|
}
|
1090
1449
|
|
1091
1450
|
/*
|
1092
|
-
*
|
1093
|
-
*
|
1451
|
+
* :call-seq:
|
1452
|
+
* namespace_scopes() → Array<Nokogiri::XML::Namespace>
|
1453
|
+
*
|
1454
|
+
* [Returns] Array of all the Namespaces on this node and its ancestors.
|
1094
1455
|
*
|
1095
|
-
*
|
1096
|
-
*
|
1097
|
-
*
|
1098
|
-
*
|
1456
|
+
* See also #namespaces
|
1457
|
+
*
|
1458
|
+
* *Example:*
|
1459
|
+
*
|
1460
|
+
* doc = Nokogiri::XML(<<~EOF)
|
1461
|
+
* <root xmlns="http://example.com/root" xmlns:bar="http://example.com/bar">
|
1462
|
+
* <first/>
|
1463
|
+
* <second xmlns="http://example.com/child"/>
|
1464
|
+
* <third xmlns:foo="http://example.com/foo"/>
|
1465
|
+
* </root>
|
1466
|
+
* EOF
|
1467
|
+
* doc.at_xpath("//root:first", "root" => "http://example.com/root").namespace_scopes
|
1468
|
+
* # => [#(Namespace:0x3c { href = "http://example.com/root" }),
|
1469
|
+
* # #(Namespace:0x50 { prefix = "bar", href = "http://example.com/bar" })]
|
1470
|
+
* doc.at_xpath("//child:second", "child" => "http://example.com/child").namespace_scopes
|
1471
|
+
* # => [#(Namespace:0x64 { href = "http://example.com/child" }),
|
1472
|
+
* # #(Namespace:0x50 { prefix = "bar", href = "http://example.com/bar" })]
|
1473
|
+
* doc.at_xpath("//root:third", "root" => "http://example.com/root").namespace_scopes
|
1474
|
+
* # => [#(Namespace:0x78 { prefix = "foo", href = "http://example.com/foo" }),
|
1475
|
+
* # #(Namespace:0x3c { href = "http://example.com/root" }),
|
1476
|
+
* # #(Namespace:0x50 { prefix = "bar", href = "http://example.com/bar" })]
|
1099
1477
|
*/
|
1100
1478
|
static VALUE
|
1101
|
-
|
1479
|
+
rb_xml_node_namespace_scopes(VALUE rb_node)
|
1102
1480
|
{
|
1103
1481
|
xmlNodePtr c_node ;
|
1104
1482
|
xmlNsPtr *namespaces;
|
1105
1483
|
VALUE scopes = rb_ary_new();
|
1106
1484
|
int j;
|
1107
1485
|
|
1108
|
-
|
1486
|
+
Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
|
1109
1487
|
|
1110
1488
|
namespaces = xmlGetNsList(c_node->doc, c_node);
|
1111
1489
|
if (!namespaces) {
|
@@ -1130,7 +1508,7 @@ static VALUE
|
|
1130
1508
|
node_type(VALUE self)
|
1131
1509
|
{
|
1132
1510
|
xmlNodePtr node;
|
1133
|
-
|
1511
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1134
1512
|
return INT2NUM((long)node->type);
|
1135
1513
|
}
|
1136
1514
|
|
@@ -1144,7 +1522,7 @@ static VALUE
|
|
1144
1522
|
set_native_content(VALUE self, VALUE content)
|
1145
1523
|
{
|
1146
1524
|
xmlNodePtr node, child, next ;
|
1147
|
-
|
1525
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1148
1526
|
|
1149
1527
|
child = node->children;
|
1150
1528
|
while (NULL != child) {
|
@@ -1158,30 +1536,6 @@ set_native_content(VALUE self, VALUE content)
|
|
1158
1536
|
return content;
|
1159
1537
|
}
|
1160
1538
|
|
1161
|
-
/*
|
1162
|
-
* call-seq:
|
1163
|
-
* content
|
1164
|
-
*
|
1165
|
-
* Returns the plaintext content for this Node. Note that entities will always
|
1166
|
-
* be expanded in the returned string.
|
1167
|
-
*/
|
1168
|
-
static VALUE
|
1169
|
-
get_native_content(VALUE self)
|
1170
|
-
{
|
1171
|
-
xmlNodePtr node;
|
1172
|
-
xmlChar *content;
|
1173
|
-
|
1174
|
-
Data_Get_Struct(self, xmlNode, node);
|
1175
|
-
|
1176
|
-
content = xmlNodeGetContent(node);
|
1177
|
-
if (content) {
|
1178
|
-
VALUE rval = NOKOGIRI_STR_NEW2(content);
|
1179
|
-
xmlFree(content);
|
1180
|
-
return rval;
|
1181
|
-
}
|
1182
|
-
return Qnil;
|
1183
|
-
}
|
1184
|
-
|
1185
1539
|
/*
|
1186
1540
|
* call-seq:
|
1187
1541
|
* lang=
|
@@ -1194,7 +1548,7 @@ set_lang(VALUE self_rb, VALUE lang_rb)
|
|
1194
1548
|
xmlNodePtr self ;
|
1195
1549
|
xmlChar *lang ;
|
1196
1550
|
|
1197
|
-
|
1551
|
+
Noko_Node_Get_Struct(self_rb, xmlNode, self);
|
1198
1552
|
lang = (xmlChar *)StringValueCStr(lang_rb);
|
1199
1553
|
|
1200
1554
|
xmlNodeSetLang(self, lang);
|
@@ -1216,7 +1570,7 @@ get_lang(VALUE self_rb)
|
|
1216
1570
|
xmlChar *lang ;
|
1217
1571
|
VALUE lang_rb ;
|
1218
1572
|
|
1219
|
-
|
1573
|
+
Noko_Node_Get_Struct(self_rb, xmlNode, self);
|
1220
1574
|
|
1221
1575
|
lang = xmlNodeGetLang(self);
|
1222
1576
|
if (lang) {
|
@@ -1245,7 +1599,7 @@ static VALUE
|
|
1245
1599
|
get_parent(VALUE self)
|
1246
1600
|
{
|
1247
1601
|
xmlNodePtr node, parent;
|
1248
|
-
|
1602
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1249
1603
|
|
1250
1604
|
parent = node->parent;
|
1251
1605
|
if (!parent) { return Qnil; }
|
@@ -1263,7 +1617,7 @@ static VALUE
|
|
1263
1617
|
set_name(VALUE self, VALUE new_name)
|
1264
1618
|
{
|
1265
1619
|
xmlNodePtr node;
|
1266
|
-
|
1620
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1267
1621
|
xmlNodeSetName(node, (xmlChar *)StringValueCStr(new_name));
|
1268
1622
|
return new_name;
|
1269
1623
|
}
|
@@ -1278,7 +1632,7 @@ static VALUE
|
|
1278
1632
|
get_name(VALUE self)
|
1279
1633
|
{
|
1280
1634
|
xmlNodePtr node;
|
1281
|
-
|
1635
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1282
1636
|
if (node->name) {
|
1283
1637
|
return NOKOGIRI_STR_NEW2(node->name);
|
1284
1638
|
}
|
@@ -1292,17 +1646,25 @@ get_name(VALUE self)
|
|
1292
1646
|
* Returns the path associated with this Node
|
1293
1647
|
*/
|
1294
1648
|
static VALUE
|
1295
|
-
|
1649
|
+
rb_xml_node_path(VALUE rb_node)
|
1296
1650
|
{
|
1297
|
-
xmlNodePtr
|
1298
|
-
xmlChar *
|
1651
|
+
xmlNodePtr c_node;
|
1652
|
+
xmlChar *c_path ;
|
1299
1653
|
VALUE rval;
|
1300
1654
|
|
1301
|
-
|
1655
|
+
Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
|
1656
|
+
|
1657
|
+
c_path = xmlGetNodePath(c_node);
|
1658
|
+
if (c_path == NULL) {
|
1659
|
+
// see https://github.com/sparklemotion/nokogiri/issues/2250
|
1660
|
+
// this behavior is clearly undesirable, but is what libxml <= 2.9.10 returned, and so we
|
1661
|
+
// do this for now to preserve the behavior across libxml2 versions.
|
1662
|
+
rval = NOKOGIRI_STR_NEW2("?");
|
1663
|
+
} else {
|
1664
|
+
rval = NOKOGIRI_STR_NEW2(c_path);
|
1665
|
+
xmlFree(c_path);
|
1666
|
+
}
|
1302
1667
|
|
1303
|
-
path = xmlGetNodePath(node);
|
1304
|
-
rval = NOKOGIRI_STR_NEW2(path);
|
1305
|
-
xmlFree(path);
|
1306
1668
|
return rval ;
|
1307
1669
|
}
|
1308
1670
|
|
@@ -1339,7 +1701,7 @@ native_write_to(
|
|
1339
1701
|
const char *before_indent;
|
1340
1702
|
xmlSaveCtxtPtr savectx;
|
1341
1703
|
|
1342
|
-
|
1704
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1343
1705
|
|
1344
1706
|
xmlIndentTreeOutput = 1;
|
1345
1707
|
|
@@ -1363,18 +1725,39 @@ native_write_to(
|
|
1363
1725
|
}
|
1364
1726
|
|
1365
1727
|
/*
|
1366
|
-
* call-seq:
|
1367
|
-
*
|
1728
|
+
* :call-seq:
|
1729
|
+
* line() → Integer
|
1730
|
+
*
|
1731
|
+
* [Returns] The line number of this Node.
|
1732
|
+
*
|
1733
|
+
* ---
|
1734
|
+
*
|
1735
|
+
* <b> ⚠ The CRuby and JRuby implementations differ in important ways! </b>
|
1736
|
+
*
|
1737
|
+
* Semantic differences:
|
1738
|
+
* - The CRuby method reflects the node's line number <i>in the parsed string</i>
|
1739
|
+
* - The JRuby method reflects the node's line number <i>in the final DOM structure</i> after
|
1740
|
+
* corrections have been applied
|
1741
|
+
*
|
1742
|
+
* Performance differences:
|
1743
|
+
* - The CRuby method is {O(1)}[https://en.wikipedia.org/wiki/Time_complexity#Constant_time]
|
1744
|
+
* (constant time)
|
1745
|
+
* - The JRuby method is {O(n)}[https://en.wikipedia.org/wiki/Time_complexity#Linear_time] (linear
|
1746
|
+
* time, where n is the number of nodes before/above the element in the DOM)
|
1368
1747
|
*
|
1369
|
-
*
|
1748
|
+
* If you'd like to help improve the JRuby implementation, please review these issues and reach out
|
1749
|
+
* to the maintainers:
|
1750
|
+
* - https://github.com/sparklemotion/nokogiri/issues/1223
|
1751
|
+
* - https://github.com/sparklemotion/nokogiri/pull/2177
|
1752
|
+
* - https://github.com/sparklemotion/nokogiri/issues/2380
|
1370
1753
|
*/
|
1371
1754
|
static VALUE
|
1372
|
-
|
1755
|
+
rb_xml_node_line(VALUE rb_node)
|
1373
1756
|
{
|
1374
|
-
xmlNodePtr
|
1375
|
-
|
1757
|
+
xmlNodePtr c_node;
|
1758
|
+
Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
|
1376
1759
|
|
1377
|
-
return INT2NUM(xmlGetLineNo(
|
1760
|
+
return INT2NUM(xmlGetLineNo(c_node));
|
1378
1761
|
}
|
1379
1762
|
|
1380
1763
|
/*
|
@@ -1384,90 +1767,56 @@ line(VALUE self)
|
|
1384
1767
|
* Sets the line for this Node. num must be less than 65535.
|
1385
1768
|
*/
|
1386
1769
|
static VALUE
|
1387
|
-
|
1388
|
-
{
|
1389
|
-
xmlNodePtr node;
|
1390
|
-
int value = NUM2INT(num);
|
1391
|
-
|
1392
|
-
Data_Get_Struct(self, xmlNode, node);
|
1393
|
-
if (value < 65535) {
|
1394
|
-
node->line = value;
|
1395
|
-
}
|
1396
|
-
|
1397
|
-
return num;
|
1398
|
-
}
|
1399
|
-
|
1400
|
-
/*
|
1401
|
-
* call-seq:
|
1402
|
-
* add_namespace_definition(prefix, href)
|
1403
|
-
*
|
1404
|
-
* Adds a namespace definition with +prefix+ using +href+ value. The result is
|
1405
|
-
* as if parsed XML for this node had included an attribute
|
1406
|
-
* 'xmlns:prefix=value'. A default namespace for this node ("xmlns=") can be
|
1407
|
-
* added by passing 'nil' for prefix. Namespaces added this way will not
|
1408
|
-
* show up in #attributes, but they will be included as an xmlns attribute
|
1409
|
-
* when the node is serialized to XML.
|
1410
|
-
*/
|
1411
|
-
static VALUE
|
1412
|
-
add_namespace_definition(VALUE rb_node, VALUE rb_prefix, VALUE rb_href)
|
1770
|
+
rb_xml_node_line_set(VALUE rb_node, VALUE rb_line_number)
|
1413
1771
|
{
|
1414
|
-
xmlNodePtr c_node
|
1415
|
-
|
1416
|
-
const xmlChar *c_prefix = (const xmlChar *)(NIL_P(rb_prefix) ? NULL : StringValueCStr(rb_prefix));
|
1417
|
-
|
1418
|
-
Data_Get_Struct(rb_node, xmlNode, c_node);
|
1419
|
-
element = c_node ;
|
1772
|
+
xmlNodePtr c_node;
|
1773
|
+
int line_number = NUM2INT(rb_line_number);
|
1420
1774
|
|
1421
|
-
|
1775
|
+
Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
|
1422
1776
|
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1777
|
+
// libxml2 optionally uses xmlNode.psvi to store longer line numbers, but only for text nodes.
|
1778
|
+
// search for "psvi" in SAX2.c and tree.c to learn more.
|
1779
|
+
if (line_number < 65535) {
|
1780
|
+
c_node->line = (short) line_number;
|
1781
|
+
} else {
|
1782
|
+
c_node->line = 65535;
|
1783
|
+
if (c_node->type == XML_TEXT_NODE) {
|
1784
|
+
c_node->psvi = (void *)(ptrdiff_t) line_number;
|
1426
1785
|
}
|
1427
|
-
c_namespace = xmlNewNs(element, (const xmlChar *)StringValueCStr(rb_href), c_prefix);
|
1428
|
-
}
|
1429
|
-
|
1430
|
-
if (!c_namespace) {
|
1431
|
-
return Qnil ;
|
1432
|
-
}
|
1433
|
-
|
1434
|
-
if (NIL_P(rb_prefix) || c_node != element) {
|
1435
|
-
xmlSetNs(c_node, c_namespace);
|
1436
1786
|
}
|
1437
1787
|
|
1438
|
-
return
|
1788
|
+
return rb_line_number;
|
1439
1789
|
}
|
1440
1790
|
|
1441
|
-
/*
|
1442
|
-
* @overload new(name, document)
|
1443
|
-
* Create a new node with +name+ sharing GC lifecycle with +document+.
|
1444
|
-
* @param name [String]
|
1445
|
-
* @param document [Nokogiri::XML::Document]
|
1446
|
-
* @yieldparam node [Nokogiri::XML::Node]
|
1447
|
-
* @return [Nokogiri::XML::Node]
|
1448
|
-
* @see Nokogiri::XML::Node#initialize
|
1449
|
-
*/
|
1791
|
+
/* :nodoc: documented in lib/nokogiri/xml/node.rb */
|
1450
1792
|
static VALUE
|
1451
1793
|
rb_xml_node_new(int argc, VALUE *argv, VALUE klass)
|
1452
1794
|
{
|
1453
|
-
|
1454
|
-
xmlNodePtr
|
1455
|
-
VALUE
|
1456
|
-
VALUE
|
1795
|
+
xmlNodePtr c_document_node;
|
1796
|
+
xmlNodePtr c_node;
|
1797
|
+
VALUE rb_name;
|
1798
|
+
VALUE rb_document_node;
|
1457
1799
|
VALUE rest;
|
1458
1800
|
VALUE rb_node;
|
1459
1801
|
|
1460
|
-
rb_scan_args(argc, argv, "2*", &
|
1802
|
+
rb_scan_args(argc, argv, "2*", &rb_name, &rb_document_node, &rest);
|
1461
1803
|
|
1462
|
-
|
1804
|
+
if (!rb_obj_is_kind_of(rb_document_node, cNokogiriXmlNode)) {
|
1805
|
+
rb_raise(rb_eArgError, "document must be a Nokogiri::XML::Node");
|
1806
|
+
}
|
1807
|
+
if (!rb_obj_is_kind_of(rb_document_node, cNokogiriXmlDocument)) {
|
1808
|
+
// TODO: deprecate allowing Node
|
1809
|
+
NOKO_WARN_DEPRECATION("Passing a Node as the second parameter to Node.new is deprecated. Please pass a Document instead, or prefer an alternative constructor like Node#add_child. This will become an error in a future release of Nokogiri.");
|
1810
|
+
}
|
1811
|
+
Noko_Node_Get_Struct(rb_document_node, xmlNode, c_document_node);
|
1463
1812
|
|
1464
|
-
|
1465
|
-
|
1466
|
-
noko_xml_document_pin_node(
|
1813
|
+
c_node = xmlNewNode(NULL, (xmlChar *)StringValueCStr(rb_name));
|
1814
|
+
c_node->doc = c_document_node->doc;
|
1815
|
+
noko_xml_document_pin_node(c_node);
|
1467
1816
|
|
1468
1817
|
rb_node = noko_xml_node_wrap(
|
1469
1818
|
klass == cNokogiriXmlNode ? (VALUE)NULL : klass,
|
1470
|
-
|
1819
|
+
c_node
|
1471
1820
|
);
|
1472
1821
|
rb_obj_call_init(rb_node, argc, argv);
|
1473
1822
|
|
@@ -1489,7 +1838,7 @@ dump_html(VALUE self)
|
|
1489
1838
|
xmlNodePtr node ;
|
1490
1839
|
VALUE html;
|
1491
1840
|
|
1492
|
-
|
1841
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1493
1842
|
|
1494
1843
|
buf = xmlBufferCreate() ;
|
1495
1844
|
htmlNodeDump(buf, node->doc, node);
|
@@ -1508,8 +1857,8 @@ static VALUE
|
|
1508
1857
|
compare(VALUE self, VALUE _other)
|
1509
1858
|
{
|
1510
1859
|
xmlNodePtr node, other;
|
1511
|
-
|
1512
|
-
|
1860
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1861
|
+
Noko_Node_Get_Struct(_other, xmlNode, other);
|
1513
1862
|
|
1514
1863
|
return INT2NUM((long)xmlXPathCmpNodes(other, node));
|
1515
1864
|
}
|
@@ -1529,7 +1878,7 @@ process_xincludes(VALUE self, VALUE options)
|
|
1529
1878
|
xmlNodePtr node;
|
1530
1879
|
VALUE error_list = rb_ary_new();
|
1531
1880
|
|
1532
|
-
|
1881
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1533
1882
|
|
1534
1883
|
xmlSetStructuredErrorFunc((void *)error_list, Nokogiri_error_array_pusher);
|
1535
1884
|
rcode = xmlXIncludeProcessTreeFlags(node, (int)NUM2INT(options));
|
@@ -1560,7 +1909,7 @@ in_context(VALUE self, VALUE _str, VALUE _options)
|
|
1560
1909
|
VALUE doc, err;
|
1561
1910
|
int doc_is_empty;
|
1562
1911
|
|
1563
|
-
|
1912
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
1564
1913
|
|
1565
1914
|
doc = DOC_RUBY_OBJECT(node->doc);
|
1566
1915
|
err = rb_iv_get(doc, "@errors");
|
@@ -1601,9 +1950,7 @@ in_context(VALUE self, VALUE _str, VALUE _options)
|
|
1601
1950
|
*/
|
1602
1951
|
child_iter = node->doc->children ;
|
1603
1952
|
while (child_iter) {
|
1604
|
-
|
1605
|
-
child_iter->parent = (xmlNodePtr)node->doc;
|
1606
|
-
}
|
1953
|
+
child_iter->parent = (xmlNodePtr)node->doc;
|
1607
1954
|
child_iter = child_iter->next;
|
1608
1955
|
}
|
1609
1956
|
|
@@ -1633,12 +1980,12 @@ in_context(VALUE self, VALUE _str, VALUE _options)
|
|
1633
1980
|
|
1634
1981
|
/* FIXME: This probably needs to handle more constants... */
|
1635
1982
|
switch (error) {
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1983
|
+
case XML_ERR_INTERNAL_ERROR:
|
1984
|
+
case XML_ERR_NO_MEMORY:
|
1985
|
+
rb_raise(rb_eRuntimeError, "error parsing fragment (%d)", error);
|
1986
|
+
break;
|
1987
|
+
default:
|
1988
|
+
break;
|
1642
1989
|
}
|
1643
1990
|
|
1644
1991
|
set = xmlXPathNodeSetCreate(NULL);
|
@@ -1654,14 +2001,12 @@ in_context(VALUE self, VALUE _str, VALUE _options)
|
|
1654
2001
|
return noko_xml_node_set_wrap(set, doc);
|
1655
2002
|
}
|
1656
2003
|
|
1657
|
-
|
1658
2004
|
VALUE
|
1659
2005
|
noko_xml_node_wrap(VALUE rb_class, xmlNodePtr c_node)
|
1660
2006
|
{
|
1661
2007
|
VALUE rb_document, rb_node_cache, rb_node;
|
1662
2008
|
nokogiriTuplePtr node_has_a_document;
|
1663
2009
|
xmlDocPtr c_doc;
|
1664
|
-
void (*mark_method)(xmlNodePtr) = NULL ;
|
1665
2010
|
|
1666
2011
|
assert(c_node);
|
1667
2012
|
|
@@ -1669,11 +2014,9 @@ noko_xml_node_wrap(VALUE rb_class, xmlNodePtr c_node)
|
|
1669
2014
|
return DOC_RUBY_OBJECT(c_node->doc);
|
1670
2015
|
}
|
1671
2016
|
|
1672
|
-
/* It's OK if the node doesn't have a fully-realized document (as in XML::Reader). */
|
1673
|
-
/* see https://github.com/sparklemotion/nokogiri/issues/95 */
|
1674
|
-
/* and https://github.com/sparklemotion/nokogiri/issues/439 */
|
1675
2017
|
c_doc = c_node->doc;
|
1676
|
-
|
2018
|
+
|
2019
|
+
// Nodes yielded from XML::Reader don't have a fully-realized Document
|
1677
2020
|
node_has_a_document = DOC_RUBY_OBJECT_TEST(c_doc);
|
1678
2021
|
|
1679
2022
|
if (c_node->_private && node_has_a_document) {
|
@@ -1682,50 +2025,48 @@ noko_xml_node_wrap(VALUE rb_class, xmlNodePtr c_node)
|
|
1682
2025
|
|
1683
2026
|
if (!RTEST(rb_class)) {
|
1684
2027
|
switch (c_node->type) {
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
2028
|
+
case XML_ELEMENT_NODE:
|
2029
|
+
rb_class = cNokogiriXmlElement;
|
2030
|
+
break;
|
2031
|
+
case XML_TEXT_NODE:
|
2032
|
+
rb_class = cNokogiriXmlText;
|
2033
|
+
break;
|
2034
|
+
case XML_ATTRIBUTE_NODE:
|
2035
|
+
rb_class = cNokogiriXmlAttr;
|
2036
|
+
break;
|
2037
|
+
case XML_ENTITY_REF_NODE:
|
2038
|
+
rb_class = cNokogiriXmlEntityReference;
|
2039
|
+
break;
|
2040
|
+
case XML_COMMENT_NODE:
|
2041
|
+
rb_class = cNokogiriXmlComment;
|
2042
|
+
break;
|
2043
|
+
case XML_DOCUMENT_FRAG_NODE:
|
2044
|
+
rb_class = cNokogiriXmlDocumentFragment;
|
2045
|
+
break;
|
2046
|
+
case XML_PI_NODE:
|
2047
|
+
rb_class = cNokogiriXmlProcessingInstruction;
|
2048
|
+
break;
|
2049
|
+
case XML_ENTITY_DECL:
|
2050
|
+
rb_class = cNokogiriXmlEntityDecl;
|
2051
|
+
break;
|
2052
|
+
case XML_CDATA_SECTION_NODE:
|
2053
|
+
rb_class = cNokogiriXmlCData;
|
2054
|
+
break;
|
2055
|
+
case XML_DTD_NODE:
|
2056
|
+
rb_class = cNokogiriXmlDtd;
|
2057
|
+
break;
|
2058
|
+
case XML_ATTRIBUTE_DECL:
|
2059
|
+
rb_class = cNokogiriXmlAttributeDecl;
|
2060
|
+
break;
|
2061
|
+
case XML_ELEMENT_DECL:
|
2062
|
+
rb_class = cNokogiriXmlElementDecl;
|
2063
|
+
break;
|
2064
|
+
default:
|
2065
|
+
rb_class = cNokogiriXmlNode;
|
1723
2066
|
}
|
1724
2067
|
}
|
1725
2068
|
|
1726
|
-
|
1727
|
-
|
1728
|
-
rb_node = Data_Wrap_Struct(rb_class, mark_method, debug_node_dealloc, c_node) ;
|
2069
|
+
rb_node = TypedData_Wrap_Struct(rb_class, &nokogiri_node_type, c_node) ;
|
1729
2070
|
c_node->_private = (void *)rb_node;
|
1730
2071
|
|
1731
2072
|
if (node_has_a_document) {
|
@@ -1762,63 +2103,63 @@ noko_init_xml_node()
|
|
1762
2103
|
{
|
1763
2104
|
cNokogiriXmlNode = rb_define_class_under(mNokogiriXml, "Node", rb_cObject);
|
1764
2105
|
|
2106
|
+
rb_undef_alloc_func(cNokogiriXmlNode);
|
2107
|
+
|
1765
2108
|
rb_define_singleton_method(cNokogiriXmlNode, "new", rb_xml_node_new, -1);
|
1766
2109
|
|
1767
|
-
rb_define_method(cNokogiriXmlNode, "add_namespace_definition",
|
2110
|
+
rb_define_method(cNokogiriXmlNode, "add_namespace_definition", rb_xml_node_add_namespace_definition, 2);
|
2111
|
+
rb_define_method(cNokogiriXmlNode, "attribute", rb_xml_node_attribute, 1);
|
2112
|
+
rb_define_method(cNokogiriXmlNode, "attribute_nodes", rb_xml_node_attribute_nodes, 0);
|
2113
|
+
rb_define_method(cNokogiriXmlNode, "attribute_with_ns", rb_xml_node_attribute_with_ns, 2);
|
2114
|
+
rb_define_method(cNokogiriXmlNode, "blank?", rb_xml_node_blank_eh, 0);
|
2115
|
+
rb_define_method(cNokogiriXmlNode, "child", rb_xml_node_child, 0);
|
2116
|
+
rb_define_method(cNokogiriXmlNode, "children", rb_xml_node_children, 0);
|
2117
|
+
rb_define_method(cNokogiriXmlNode, "content", rb_xml_node_content, 0);
|
2118
|
+
rb_define_method(cNokogiriXmlNode, "create_external_subset", create_external_subset, 3);
|
2119
|
+
rb_define_method(cNokogiriXmlNode, "create_internal_subset", create_internal_subset, 3);
|
2120
|
+
rb_define_method(cNokogiriXmlNode, "document", rb_xml_node_document, 0);
|
2121
|
+
rb_define_method(cNokogiriXmlNode, "dup", duplicate_node, -1);
|
2122
|
+
rb_define_method(cNokogiriXmlNode, "element_children", rb_xml_node_element_children, 0);
|
2123
|
+
rb_define_method(cNokogiriXmlNode, "encode_special_chars", encode_special_chars, 1);
|
2124
|
+
rb_define_method(cNokogiriXmlNode, "external_subset", external_subset, 0);
|
2125
|
+
rb_define_method(cNokogiriXmlNode, "first_element_child", rb_xml_node_first_element_child, 0);
|
2126
|
+
rb_define_method(cNokogiriXmlNode, "internal_subset", internal_subset, 0);
|
2127
|
+
rb_define_method(cNokogiriXmlNode, "key?", key_eh, 1);
|
2128
|
+
rb_define_method(cNokogiriXmlNode, "lang", get_lang, 0);
|
2129
|
+
rb_define_method(cNokogiriXmlNode, "lang=", set_lang, 1);
|
2130
|
+
rb_define_method(cNokogiriXmlNode, "last_element_child", rb_xml_node_last_element_child, 0);
|
2131
|
+
rb_define_method(cNokogiriXmlNode, "line", rb_xml_node_line, 0);
|
2132
|
+
rb_define_method(cNokogiriXmlNode, "line=", rb_xml_node_line_set, 1);
|
2133
|
+
rb_define_method(cNokogiriXmlNode, "namespace", rb_xml_node_namespace, 0);
|
2134
|
+
rb_define_method(cNokogiriXmlNode, "namespace_definitions", namespace_definitions, 0);
|
2135
|
+
rb_define_method(cNokogiriXmlNode, "namespace_scopes", rb_xml_node_namespace_scopes, 0);
|
2136
|
+
rb_define_method(cNokogiriXmlNode, "namespaced_key?", namespaced_key_eh, 2);
|
2137
|
+
rb_define_method(cNokogiriXmlNode, "native_content=", set_native_content, 1);
|
2138
|
+
rb_define_method(cNokogiriXmlNode, "next_element", next_element, 0);
|
2139
|
+
rb_define_method(cNokogiriXmlNode, "next_sibling", next_sibling, 0);
|
1768
2140
|
rb_define_method(cNokogiriXmlNode, "node_name", get_name, 0);
|
1769
|
-
rb_define_method(cNokogiriXmlNode, "document", document, 0);
|
1770
2141
|
rb_define_method(cNokogiriXmlNode, "node_name=", set_name, 1);
|
2142
|
+
rb_define_method(cNokogiriXmlNode, "node_type", node_type, 0);
|
1771
2143
|
rb_define_method(cNokogiriXmlNode, "parent", get_parent, 0);
|
1772
|
-
rb_define_method(cNokogiriXmlNode, "
|
1773
|
-
rb_define_method(cNokogiriXmlNode, "
|
1774
|
-
rb_define_method(cNokogiriXmlNode, "last_element_child", last_element_child, 0);
|
1775
|
-
rb_define_method(cNokogiriXmlNode, "children", children, 0);
|
1776
|
-
rb_define_method(cNokogiriXmlNode, "element_children", element_children, 0);
|
1777
|
-
rb_define_method(cNokogiriXmlNode, "next_sibling", next_sibling, 0);
|
1778
|
-
rb_define_method(cNokogiriXmlNode, "previous_sibling", previous_sibling, 0);
|
1779
|
-
rb_define_method(cNokogiriXmlNode, "next_element", next_element, 0);
|
2144
|
+
rb_define_method(cNokogiriXmlNode, "path", rb_xml_node_path, 0);
|
2145
|
+
rb_define_method(cNokogiriXmlNode, "pointer_id", rb_xml_node_pointer_id, 0);
|
1780
2146
|
rb_define_method(cNokogiriXmlNode, "previous_element", previous_element, 0);
|
1781
|
-
rb_define_method(cNokogiriXmlNode, "
|
1782
|
-
rb_define_method(cNokogiriXmlNode, "path", path, 0);
|
1783
|
-
rb_define_method(cNokogiriXmlNode, "key?", key_eh, 1);
|
1784
|
-
rb_define_method(cNokogiriXmlNode, "namespaced_key?", namespaced_key_eh, 2);
|
1785
|
-
rb_define_method(cNokogiriXmlNode, "blank?", blank_eh, 0);
|
1786
|
-
rb_define_method(cNokogiriXmlNode, "attribute_nodes", attribute_nodes, 0);
|
1787
|
-
rb_define_method(cNokogiriXmlNode, "attribute", attr, 1);
|
1788
|
-
rb_define_method(cNokogiriXmlNode, "attribute_with_ns", attribute_with_ns, 2);
|
1789
|
-
rb_define_method(cNokogiriXmlNode, "namespace", noko_xml_node_namespace, 0);
|
1790
|
-
rb_define_method(cNokogiriXmlNode, "namespace_definitions", namespace_definitions, 0);
|
1791
|
-
rb_define_method(cNokogiriXmlNode, "namespace_scopes", namespace_scopes, 0);
|
1792
|
-
rb_define_method(cNokogiriXmlNode, "encode_special_chars", encode_special_chars, 1);
|
1793
|
-
rb_define_method(cNokogiriXmlNode, "dup", duplicate_node, -1);
|
2147
|
+
rb_define_method(cNokogiriXmlNode, "previous_sibling", previous_sibling, 0);
|
1794
2148
|
rb_define_method(cNokogiriXmlNode, "unlink", unlink_node, 0);
|
1795
|
-
rb_define_method(cNokogiriXmlNode, "internal_subset", internal_subset, 0);
|
1796
|
-
rb_define_method(cNokogiriXmlNode, "external_subset", external_subset, 0);
|
1797
|
-
rb_define_method(cNokogiriXmlNode, "create_internal_subset", create_internal_subset, 3);
|
1798
|
-
rb_define_method(cNokogiriXmlNode, "create_external_subset", create_external_subset, 3);
|
1799
|
-
rb_define_method(cNokogiriXmlNode, "pointer_id", pointer_id, 0);
|
1800
|
-
rb_define_method(cNokogiriXmlNode, "line", line, 0);
|
1801
|
-
rb_define_method(cNokogiriXmlNode, "line=", set_line, 1);
|
1802
|
-
rb_define_method(cNokogiriXmlNode, "content", get_native_content, 0);
|
1803
|
-
rb_define_method(cNokogiriXmlNode, "native_content=", set_native_content, 1);
|
1804
|
-
rb_define_method(cNokogiriXmlNode, "lang", get_lang, 0);
|
1805
|
-
rb_define_method(cNokogiriXmlNode, "lang=", set_lang, 1);
|
1806
2149
|
|
1807
|
-
rb_define_private_method(cNokogiriXmlNode, "process_xincludes", process_xincludes, 1);
|
1808
|
-
rb_define_private_method(cNokogiriXmlNode, "in_context", in_context, 2);
|
1809
2150
|
rb_define_private_method(cNokogiriXmlNode, "add_child_node", add_child, 1);
|
1810
|
-
rb_define_private_method(cNokogiriXmlNode, "add_previous_sibling_node", add_previous_sibling, 1);
|
1811
2151
|
rb_define_private_method(cNokogiriXmlNode, "add_next_sibling_node", add_next_sibling, 1);
|
1812
|
-
rb_define_private_method(cNokogiriXmlNode, "
|
2152
|
+
rb_define_private_method(cNokogiriXmlNode, "add_previous_sibling_node", add_previous_sibling, 1);
|
2153
|
+
rb_define_private_method(cNokogiriXmlNode, "compare", compare, 1);
|
1813
2154
|
rb_define_private_method(cNokogiriXmlNode, "dump_html", dump_html, 0);
|
1814
|
-
rb_define_private_method(cNokogiriXmlNode, "native_write_to", native_write_to, 4);
|
1815
2155
|
rb_define_private_method(cNokogiriXmlNode, "get", get, 1);
|
2156
|
+
rb_define_private_method(cNokogiriXmlNode, "in_context", in_context, 2);
|
2157
|
+
rb_define_private_method(cNokogiriXmlNode, "native_write_to", native_write_to, 4);
|
2158
|
+
rb_define_private_method(cNokogiriXmlNode, "process_xincludes", process_xincludes, 1);
|
2159
|
+
rb_define_private_method(cNokogiriXmlNode, "replace_node", replace, 1);
|
1816
2160
|
rb_define_private_method(cNokogiriXmlNode, "set", set, 2);
|
1817
2161
|
rb_define_private_method(cNokogiriXmlNode, "set_namespace", set_namespace, 1);
|
1818
|
-
rb_define_private_method(cNokogiriXmlNode, "compare", compare, 1);
|
1819
2162
|
|
1820
2163
|
id_decorate = rb_intern("decorate");
|
1821
2164
|
id_decorate_bang = rb_intern("decorate!");
|
1822
2165
|
}
|
1823
|
-
|
1824
|
-
/* vim: set noet sw=4 sws=4 */
|