nokogiri 1.3.0-x86-mswin32
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.
- data/.autotest +27 -0
- data/CHANGELOG.ja.rdoc +233 -0
- data/CHANGELOG.rdoc +222 -0
- data/Manifest.txt +247 -0
- data/README.ja.rdoc +103 -0
- data/README.rdoc +117 -0
- data/Rakefile +205 -0
- data/bin/nokogiri +47 -0
- data/ext/nokogiri/extconf.rb +89 -0
- data/ext/nokogiri/html_document.c +183 -0
- data/ext/nokogiri/html_document.h +10 -0
- data/ext/nokogiri/html_element_description.c +272 -0
- data/ext/nokogiri/html_element_description.h +10 -0
- data/ext/nokogiri/html_entity_lookup.c +30 -0
- data/ext/nokogiri/html_entity_lookup.h +8 -0
- data/ext/nokogiri/html_sax_parser.c +57 -0
- data/ext/nokogiri/html_sax_parser.h +11 -0
- data/ext/nokogiri/iconv.dll +0 -0
- data/ext/nokogiri/libexslt.dll +0 -0
- data/ext/nokogiri/libxml2.dll +0 -0
- data/ext/nokogiri/libxslt.dll +0 -0
- data/ext/nokogiri/nokogiri.c +81 -0
- data/ext/nokogiri/nokogiri.h +149 -0
- data/ext/nokogiri/xml_attr.c +92 -0
- data/ext/nokogiri/xml_attr.h +9 -0
- data/ext/nokogiri/xml_cdata.c +53 -0
- data/ext/nokogiri/xml_cdata.h +9 -0
- data/ext/nokogiri/xml_comment.c +51 -0
- data/ext/nokogiri/xml_comment.h +9 -0
- data/ext/nokogiri/xml_document.c +308 -0
- data/ext/nokogiri/xml_document.h +21 -0
- data/ext/nokogiri/xml_document_fragment.c +48 -0
- data/ext/nokogiri/xml_document_fragment.h +10 -0
- data/ext/nokogiri/xml_dtd.c +102 -0
- data/ext/nokogiri/xml_dtd.h +8 -0
- data/ext/nokogiri/xml_entity_reference.c +50 -0
- data/ext/nokogiri/xml_entity_reference.h +9 -0
- data/ext/nokogiri/xml_io.c +24 -0
- data/ext/nokogiri/xml_io.h +10 -0
- data/ext/nokogiri/xml_namespace.c +69 -0
- data/ext/nokogiri/xml_namespace.h +12 -0
- data/ext/nokogiri/xml_node.c +928 -0
- data/ext/nokogiri/xml_node.h +14 -0
- data/ext/nokogiri/xml_node_set.c +386 -0
- data/ext/nokogiri/xml_node_set.h +9 -0
- data/ext/nokogiri/xml_processing_instruction.c +54 -0
- data/ext/nokogiri/xml_processing_instruction.h +9 -0
- data/ext/nokogiri/xml_reader.c +572 -0
- data/ext/nokogiri/xml_reader.h +10 -0
- data/ext/nokogiri/xml_relax_ng.c +106 -0
- data/ext/nokogiri/xml_relax_ng.h +9 -0
- data/ext/nokogiri/xml_sax_parser.c +336 -0
- data/ext/nokogiri/xml_sax_parser.h +10 -0
- data/ext/nokogiri/xml_sax_push_parser.c +86 -0
- data/ext/nokogiri/xml_sax_push_parser.h +9 -0
- data/ext/nokogiri/xml_schema.c +107 -0
- data/ext/nokogiri/xml_schema.h +9 -0
- data/ext/nokogiri/xml_syntax_error.c +203 -0
- data/ext/nokogiri/xml_syntax_error.h +12 -0
- data/ext/nokogiri/xml_text.c +47 -0
- data/ext/nokogiri/xml_text.h +9 -0
- data/ext/nokogiri/xml_xpath.c +53 -0
- data/ext/nokogiri/xml_xpath.h +11 -0
- data/ext/nokogiri/xml_xpath_context.c +252 -0
- data/ext/nokogiri/xml_xpath_context.h +9 -0
- data/ext/nokogiri/xslt_stylesheet.c +131 -0
- data/ext/nokogiri/xslt_stylesheet.h +9 -0
- data/ext/nokogiri/zlib1.dll +0 -0
- data/lib/action-nokogiri.rb +36 -0
- data/lib/nokogiri.rb +110 -0
- data/lib/nokogiri/1.8/nokogiri.so +0 -0
- data/lib/nokogiri/1.9/nokogiri.so +0 -0
- data/lib/nokogiri/css.rb +25 -0
- data/lib/nokogiri/css/generated_parser.rb +748 -0
- data/lib/nokogiri/css/generated_tokenizer.rb +144 -0
- data/lib/nokogiri/css/node.rb +107 -0
- data/lib/nokogiri/css/parser.rb +82 -0
- data/lib/nokogiri/css/parser.y +227 -0
- data/lib/nokogiri/css/syntax_error.rb +7 -0
- data/lib/nokogiri/css/tokenizer.rb +11 -0
- data/lib/nokogiri/css/tokenizer.rex +54 -0
- data/lib/nokogiri/css/xpath_visitor.rb +172 -0
- data/lib/nokogiri/decorators.rb +2 -0
- data/lib/nokogiri/decorators/hpricot.rb +3 -0
- data/lib/nokogiri/decorators/hpricot/node.rb +56 -0
- data/lib/nokogiri/decorators/hpricot/node_set.rb +54 -0
- data/lib/nokogiri/decorators/hpricot/xpath_visitor.rb +30 -0
- data/lib/nokogiri/decorators/slop.rb +33 -0
- data/lib/nokogiri/ffi/html/document.rb +37 -0
- data/lib/nokogiri/ffi/html/element_description.rb +85 -0
- data/lib/nokogiri/ffi/html/entity_lookup.rb +16 -0
- data/lib/nokogiri/ffi/html/sax/parser.rb +21 -0
- data/lib/nokogiri/ffi/io_callbacks.rb +32 -0
- data/lib/nokogiri/ffi/libxml.rb +314 -0
- data/lib/nokogiri/ffi/structs/common_node.rb +26 -0
- data/lib/nokogiri/ffi/structs/html_elem_desc.rb +24 -0
- data/lib/nokogiri/ffi/structs/html_entity_desc.rb +13 -0
- data/lib/nokogiri/ffi/structs/xml_alloc.rb +16 -0
- data/lib/nokogiri/ffi/structs/xml_attr.rb +19 -0
- data/lib/nokogiri/ffi/structs/xml_buffer.rb +16 -0
- data/lib/nokogiri/ffi/structs/xml_document.rb +108 -0
- data/lib/nokogiri/ffi/structs/xml_dtd.rb +26 -0
- data/lib/nokogiri/ffi/structs/xml_node.rb +28 -0
- data/lib/nokogiri/ffi/structs/xml_node_set.rb +53 -0
- data/lib/nokogiri/ffi/structs/xml_notation.rb +11 -0
- data/lib/nokogiri/ffi/structs/xml_ns.rb +15 -0
- data/lib/nokogiri/ffi/structs/xml_relax_ng.rb +14 -0
- data/lib/nokogiri/ffi/structs/xml_sax_handler.rb +51 -0
- data/lib/nokogiri/ffi/structs/xml_sax_push_parser_context.rb +14 -0
- data/lib/nokogiri/ffi/structs/xml_schema.rb +13 -0
- data/lib/nokogiri/ffi/structs/xml_syntax_error.rb +31 -0
- data/lib/nokogiri/ffi/structs/xml_text_reader.rb +12 -0
- data/lib/nokogiri/ffi/structs/xml_xpath_context.rb +37 -0
- data/lib/nokogiri/ffi/structs/xml_xpath_object.rb +35 -0
- data/lib/nokogiri/ffi/structs/xml_xpath_parser_context.rb +20 -0
- data/lib/nokogiri/ffi/structs/xslt_stylesheet.rb +13 -0
- data/lib/nokogiri/ffi/xml/attr.rb +41 -0
- data/lib/nokogiri/ffi/xml/cdata.rb +19 -0
- data/lib/nokogiri/ffi/xml/comment.rb +18 -0
- data/lib/nokogiri/ffi/xml/document.rb +107 -0
- data/lib/nokogiri/ffi/xml/document_fragment.rb +26 -0
- data/lib/nokogiri/ffi/xml/dtd.rb +42 -0
- data/lib/nokogiri/ffi/xml/entity_reference.rb +19 -0
- data/lib/nokogiri/ffi/xml/namespace.rb +38 -0
- data/lib/nokogiri/ffi/xml/node.rb +380 -0
- data/lib/nokogiri/ffi/xml/node_set.rb +130 -0
- data/lib/nokogiri/ffi/xml/processing_instruction.rb +20 -0
- data/lib/nokogiri/ffi/xml/reader.rb +217 -0
- data/lib/nokogiri/ffi/xml/relax_ng.rb +51 -0
- data/lib/nokogiri/ffi/xml/sax/parser.rb +148 -0
- data/lib/nokogiri/ffi/xml/sax/push_parser.rb +38 -0
- data/lib/nokogiri/ffi/xml/schema.rb +55 -0
- data/lib/nokogiri/ffi/xml/syntax_error.rb +76 -0
- data/lib/nokogiri/ffi/xml/text.rb +18 -0
- data/lib/nokogiri/ffi/xml/xpath.rb +19 -0
- data/lib/nokogiri/ffi/xml/xpath_context.rb +135 -0
- data/lib/nokogiri/ffi/xslt/stylesheet.rb +47 -0
- data/lib/nokogiri/hpricot.rb +62 -0
- data/lib/nokogiri/html.rb +34 -0
- data/lib/nokogiri/html/builder.rb +35 -0
- data/lib/nokogiri/html/document.rb +71 -0
- data/lib/nokogiri/html/document_fragment.rb +15 -0
- data/lib/nokogiri/html/element_description.rb +23 -0
- data/lib/nokogiri/html/entity_lookup.rb +13 -0
- data/lib/nokogiri/html/sax/parser.rb +47 -0
- data/lib/nokogiri/nokogiri.rb +1 -0
- data/lib/nokogiri/syntax_error.rb +4 -0
- data/lib/nokogiri/version.rb +29 -0
- data/lib/nokogiri/version_warning.rb +11 -0
- data/lib/nokogiri/xml.rb +62 -0
- data/lib/nokogiri/xml/attr.rb +9 -0
- data/lib/nokogiri/xml/builder.rb +254 -0
- data/lib/nokogiri/xml/cdata.rb +11 -0
- data/lib/nokogiri/xml/document.rb +100 -0
- data/lib/nokogiri/xml/document_fragment.rb +49 -0
- data/lib/nokogiri/xml/dtd.rb +11 -0
- data/lib/nokogiri/xml/entity_declaration.rb +11 -0
- data/lib/nokogiri/xml/fragment_handler.rb +55 -0
- data/lib/nokogiri/xml/namespace.rb +7 -0
- data/lib/nokogiri/xml/node.rb +745 -0
- data/lib/nokogiri/xml/node/save_options.rb +42 -0
- data/lib/nokogiri/xml/node_set.rb +238 -0
- data/lib/nokogiri/xml/notation.rb +6 -0
- data/lib/nokogiri/xml/parse_options.rb +80 -0
- data/lib/nokogiri/xml/processing_instruction.rb +8 -0
- data/lib/nokogiri/xml/reader.rb +66 -0
- data/lib/nokogiri/xml/relax_ng.rb +32 -0
- data/lib/nokogiri/xml/sax.rb +3 -0
- data/lib/nokogiri/xml/sax/document.rb +143 -0
- data/lib/nokogiri/xml/sax/parser.rb +101 -0
- data/lib/nokogiri/xml/sax/push_parser.rb +60 -0
- data/lib/nokogiri/xml/schema.rb +65 -0
- data/lib/nokogiri/xml/syntax_error.rb +34 -0
- data/lib/nokogiri/xml/xpath.rb +10 -0
- data/lib/nokogiri/xml/xpath/syntax_error.rb +8 -0
- data/lib/nokogiri/xml/xpath_context.rb +16 -0
- data/lib/nokogiri/xslt.rb +48 -0
- data/lib/nokogiri/xslt/stylesheet.rb +25 -0
- data/lib/xsd/xmlparser/nokogiri.rb +64 -0
- data/tasks/test.rb +161 -0
- data/test/css/test_nthiness.rb +160 -0
- data/test/css/test_parser.rb +277 -0
- data/test/css/test_tokenizer.rb +176 -0
- data/test/css/test_xpath_visitor.rb +76 -0
- data/test/ffi/test_document.rb +35 -0
- data/test/files/address_book.rlx +12 -0
- data/test/files/address_book.xml +10 -0
- data/test/files/dont_hurt_em_why.xml +422 -0
- data/test/files/exslt.xml +8 -0
- data/test/files/exslt.xslt +35 -0
- data/test/files/po.xml +32 -0
- data/test/files/po.xsd +66 -0
- data/test/files/staff.xml +59 -0
- data/test/files/staff.xslt +32 -0
- data/test/files/tlm.html +850 -0
- data/test/helper.rb +123 -0
- data/test/hpricot/files/basic.xhtml +17 -0
- data/test/hpricot/files/boingboing.html +2266 -0
- data/test/hpricot/files/cy0.html +3653 -0
- data/test/hpricot/files/immob.html +400 -0
- data/test/hpricot/files/pace_application.html +1320 -0
- data/test/hpricot/files/tenderlove.html +16 -0
- data/test/hpricot/files/uswebgen.html +220 -0
- data/test/hpricot/files/utf8.html +1054 -0
- data/test/hpricot/files/week9.html +1723 -0
- data/test/hpricot/files/why.xml +19 -0
- data/test/hpricot/load_files.rb +11 -0
- data/test/hpricot/test_alter.rb +68 -0
- data/test/hpricot/test_builder.rb +20 -0
- data/test/hpricot/test_parser.rb +426 -0
- data/test/hpricot/test_paths.rb +15 -0
- data/test/hpricot/test_preserved.rb +77 -0
- data/test/hpricot/test_xml.rb +30 -0
- data/test/html/sax/test_parser.rb +52 -0
- data/test/html/test_builder.rb +156 -0
- data/test/html/test_document.rb +361 -0
- data/test/html/test_document_encoding.rb +46 -0
- data/test/html/test_document_fragment.rb +97 -0
- data/test/html/test_element_description.rb +95 -0
- data/test/html/test_named_characters.rb +14 -0
- data/test/html/test_node.rb +165 -0
- data/test/test_convert_xpath.rb +186 -0
- data/test/test_css_cache.rb +56 -0
- data/test/test_gc.rb +15 -0
- data/test/test_memory_leak.rb +77 -0
- data/test/test_nokogiri.rb +127 -0
- data/test/test_reader.rb +316 -0
- data/test/test_xslt_transforms.rb +131 -0
- data/test/xml/node/test_save_options.rb +20 -0
- data/test/xml/node/test_subclass.rb +44 -0
- data/test/xml/sax/test_parser.rb +169 -0
- data/test/xml/sax/test_push_parser.rb +92 -0
- data/test/xml/test_attr.rb +38 -0
- data/test/xml/test_builder.rb +73 -0
- data/test/xml/test_cdata.rb +38 -0
- data/test/xml/test_comment.rb +23 -0
- data/test/xml/test_document.rb +397 -0
- data/test/xml/test_document_encoding.rb +26 -0
- data/test/xml/test_document_fragment.rb +76 -0
- data/test/xml/test_dtd.rb +42 -0
- data/test/xml/test_dtd_encoding.rb +31 -0
- data/test/xml/test_entity_reference.rb +21 -0
- data/test/xml/test_namespace.rb +43 -0
- data/test/xml/test_node.rb +808 -0
- data/test/xml/test_node_attributes.rb +34 -0
- data/test/xml/test_node_encoding.rb +84 -0
- data/test/xml/test_node_set.rb +368 -0
- data/test/xml/test_parse_options.rb +52 -0
- data/test/xml/test_processing_instruction.rb +30 -0
- data/test/xml/test_reader_encoding.rb +126 -0
- data/test/xml/test_relax_ng.rb +60 -0
- data/test/xml/test_schema.rb +65 -0
- data/test/xml/test_text.rb +18 -0
- data/test/xml/test_unparented_node.rb +381 -0
- data/test/xml/test_xpath.rb +106 -0
- metadata +409 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
#ifndef NOKOGIRI_XML_DOCUMENT
|
2
|
+
#define NOKOGIRI_XML_DOCUMENT
|
3
|
+
|
4
|
+
#include <nokogiri.h>
|
5
|
+
|
6
|
+
struct _nokogiriTuple {
|
7
|
+
xmlDocPtr doc;
|
8
|
+
xmlNodeSetPtr unlinkedNodes;
|
9
|
+
};
|
10
|
+
typedef struct _nokogiriTuple nokogiriTuple;
|
11
|
+
typedef nokogiriTuple * nokogiriTuplePtr;
|
12
|
+
|
13
|
+
void init_xml_document();
|
14
|
+
VALUE Nokogiri_wrap_xml_document(VALUE klass, xmlDocPtr doc);
|
15
|
+
|
16
|
+
#define DOC_RUBY_OBJECT_TEST(x) ((nokogiriTuplePtr)(x->_private))
|
17
|
+
#define DOC_RUBY_OBJECT(x) ((VALUE)((nokogiriTuplePtr)(x->_private))->doc)
|
18
|
+
#define DOC_UNLINKED_NODE_SET(x) ((xmlNodeSetPtr)((nokogiriTuplePtr)(x->_private))->unlinkedNodes)
|
19
|
+
|
20
|
+
extern VALUE cNokogiriXmlDocument ;
|
21
|
+
#endif
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#include <xml_document_fragment.h>
|
2
|
+
|
3
|
+
/*
|
4
|
+
* call-seq:
|
5
|
+
* new(document)
|
6
|
+
*
|
7
|
+
* Create a new DocumentFragment element on the +document+
|
8
|
+
*/
|
9
|
+
static VALUE new(int argc, VALUE *argv, VALUE klass)
|
10
|
+
{
|
11
|
+
xmlDocPtr xml_doc;
|
12
|
+
VALUE document;
|
13
|
+
VALUE rest;
|
14
|
+
|
15
|
+
rb_scan_args(argc, argv, "1*", &document, &rest);
|
16
|
+
|
17
|
+
Data_Get_Struct(document, xmlDoc, xml_doc);
|
18
|
+
|
19
|
+
xmlNodePtr node = xmlNewDocFragment(xml_doc->doc);
|
20
|
+
if(node->doc->children)
|
21
|
+
node->ns = node->doc->children->ns;
|
22
|
+
|
23
|
+
NOKOGIRI_ROOT_NODE(node);
|
24
|
+
|
25
|
+
VALUE rb_node = Nokogiri_wrap_xml_node(klass, node);
|
26
|
+
rb_funcall2(rb_node, rb_intern("initialize"), argc, argv);
|
27
|
+
|
28
|
+
if(rb_block_given_p()) rb_yield(rb_node);
|
29
|
+
|
30
|
+
return rb_node;
|
31
|
+
}
|
32
|
+
|
33
|
+
VALUE cNokogiriXmlDocumentFragment;
|
34
|
+
void init_xml_document_fragment()
|
35
|
+
{
|
36
|
+
VALUE nokogiri = rb_define_module("Nokogiri");
|
37
|
+
VALUE xml = rb_define_module_under(nokogiri, "XML");
|
38
|
+
VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
|
39
|
+
|
40
|
+
/*
|
41
|
+
* DocumentFragment represents a DocumentFragment node in an xml document.
|
42
|
+
*/
|
43
|
+
VALUE klass = rb_define_class_under(xml, "DocumentFragment", node);
|
44
|
+
|
45
|
+
cNokogiriXmlDocumentFragment = klass;
|
46
|
+
|
47
|
+
rb_define_singleton_method(klass, "new", new, -1);
|
48
|
+
}
|
@@ -0,0 +1,102 @@
|
|
1
|
+
#include <xml_dtd.h>
|
2
|
+
|
3
|
+
static void notation_copier(void *payload, void *data, xmlChar *name)
|
4
|
+
{
|
5
|
+
VALUE hash = (VALUE)data;
|
6
|
+
VALUE klass = rb_const_get(mNokogiriXml, rb_intern("Notation"));
|
7
|
+
|
8
|
+
xmlNotationPtr c_notation = (xmlNotationPtr)payload;
|
9
|
+
|
10
|
+
VALUE notation = rb_funcall(klass, rb_intern("new"), 3,
|
11
|
+
c_notation->name ? NOKOGIRI_STR_NEW2(c_notation->name, "UTF-8") : Qnil,
|
12
|
+
c_notation->PublicID ? NOKOGIRI_STR_NEW2(c_notation->PublicID, "UTF-8") : Qnil,
|
13
|
+
c_notation->SystemID ? NOKOGIRI_STR_NEW2(c_notation->SystemID, "UTF-8") : Qnil);
|
14
|
+
|
15
|
+
rb_hash_aset(hash, NOKOGIRI_STR_NEW2(name, "UTF-8"),notation);
|
16
|
+
}
|
17
|
+
|
18
|
+
static void element_copier(void *_payload, void *data, xmlChar *name)
|
19
|
+
{
|
20
|
+
VALUE hash = (VALUE)data;
|
21
|
+
xmlNodePtr payload = (xmlNodePtr)_payload;
|
22
|
+
|
23
|
+
VALUE element = Nokogiri_wrap_xml_node(Qnil, payload);
|
24
|
+
|
25
|
+
rb_hash_aset(hash, NOKOGIRI_STR_NEW2(name, payload->doc->encoding), element);
|
26
|
+
}
|
27
|
+
|
28
|
+
/*
|
29
|
+
* call-seq:
|
30
|
+
* entities
|
31
|
+
*
|
32
|
+
* Get a hash of the elements for this DTD.
|
33
|
+
*/
|
34
|
+
static VALUE entities(VALUE self)
|
35
|
+
{
|
36
|
+
xmlDtdPtr dtd;
|
37
|
+
Data_Get_Struct(self, xmlDtd, dtd);
|
38
|
+
|
39
|
+
if(!dtd->entities) return Qnil;
|
40
|
+
|
41
|
+
VALUE hash = rb_hash_new();
|
42
|
+
|
43
|
+
xmlHashScan((xmlHashTablePtr)dtd->entities, element_copier, (void *)hash);
|
44
|
+
|
45
|
+
return hash;
|
46
|
+
}
|
47
|
+
|
48
|
+
/*
|
49
|
+
* call-seq:
|
50
|
+
* notations
|
51
|
+
*
|
52
|
+
* Get a hash of the notations for this DTD.
|
53
|
+
*/
|
54
|
+
static VALUE notations(VALUE self)
|
55
|
+
{
|
56
|
+
xmlDtdPtr dtd;
|
57
|
+
Data_Get_Struct(self, xmlDtd, dtd);
|
58
|
+
|
59
|
+
if(!dtd->notations) return Qnil;
|
60
|
+
|
61
|
+
VALUE hash = rb_hash_new();
|
62
|
+
|
63
|
+
xmlHashScan((xmlHashTablePtr)dtd->notations, notation_copier, (void *)hash);
|
64
|
+
|
65
|
+
return hash;
|
66
|
+
}
|
67
|
+
|
68
|
+
/*
|
69
|
+
* call-seq:
|
70
|
+
* elements
|
71
|
+
*
|
72
|
+
* Get a hash of the elements for this DTD.
|
73
|
+
*/
|
74
|
+
static VALUE elements(VALUE self)
|
75
|
+
{
|
76
|
+
xmlDtdPtr dtd;
|
77
|
+
Data_Get_Struct(self, xmlDtd, dtd);
|
78
|
+
|
79
|
+
if(!dtd->elements) return Qnil;
|
80
|
+
|
81
|
+
VALUE hash = rb_hash_new();
|
82
|
+
|
83
|
+
xmlHashScan((xmlHashTablePtr)dtd->elements, element_copier, (void *)hash);
|
84
|
+
|
85
|
+
return hash;
|
86
|
+
}
|
87
|
+
|
88
|
+
void init_xml_dtd()
|
89
|
+
{
|
90
|
+
VALUE nokogiri = rb_define_module("Nokogiri");
|
91
|
+
VALUE xml = rb_define_module_under(nokogiri, "XML");
|
92
|
+
VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
|
93
|
+
|
94
|
+
/*
|
95
|
+
* Nokogiri::XML::DTD wraps DTD nodes in an XML document
|
96
|
+
*/
|
97
|
+
VALUE klass = rb_define_class_under(xml, "DTD", node);
|
98
|
+
|
99
|
+
rb_define_method(klass, "notations", notations, 0);
|
100
|
+
rb_define_method(klass, "elements", elements, 0);
|
101
|
+
rb_define_method(klass, "entities", entities, 0);
|
102
|
+
}
|
@@ -0,0 +1,50 @@
|
|
1
|
+
#include <xml_entity_reference.h>
|
2
|
+
|
3
|
+
/*
|
4
|
+
* call-seq:
|
5
|
+
* new(document, content)
|
6
|
+
*
|
7
|
+
* Create a new EntityReference element on the +document+ with +name+
|
8
|
+
*/
|
9
|
+
static VALUE new(int argc, VALUE *argv, VALUE klass)
|
10
|
+
{
|
11
|
+
xmlDocPtr xml_doc;
|
12
|
+
VALUE document;
|
13
|
+
VALUE name;
|
14
|
+
VALUE rest;
|
15
|
+
|
16
|
+
rb_scan_args(argc, argv, "2*", &document, &name, &rest);
|
17
|
+
|
18
|
+
Data_Get_Struct(document, xmlDoc, xml_doc);
|
19
|
+
|
20
|
+
xmlNodePtr node = xmlNewReference(
|
21
|
+
xml_doc,
|
22
|
+
(const xmlChar *)StringValuePtr(name)
|
23
|
+
);
|
24
|
+
|
25
|
+
NOKOGIRI_ROOT_NODE(node);
|
26
|
+
|
27
|
+
VALUE rb_node = Nokogiri_wrap_xml_node(klass, node);
|
28
|
+
rb_funcall2(rb_node, rb_intern("initialize"), argc, argv);
|
29
|
+
|
30
|
+
if(rb_block_given_p()) rb_yield(rb_node);
|
31
|
+
|
32
|
+
return rb_node;
|
33
|
+
}
|
34
|
+
|
35
|
+
VALUE cNokogiriXmlEntityReference;
|
36
|
+
void init_xml_entity_reference()
|
37
|
+
{
|
38
|
+
VALUE nokogiri = rb_define_module("Nokogiri");
|
39
|
+
VALUE xml = rb_define_module_under(nokogiri, "XML");
|
40
|
+
VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
|
41
|
+
|
42
|
+
/*
|
43
|
+
* EntityReference represents an EntityReference node in an xml document.
|
44
|
+
*/
|
45
|
+
VALUE klass = rb_define_class_under(xml, "EntityReference", node);
|
46
|
+
|
47
|
+
cNokogiriXmlEntityReference = klass;
|
48
|
+
|
49
|
+
rb_define_singleton_method(klass, "new", new, -1);
|
50
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#include <xml_io.h>
|
2
|
+
|
3
|
+
int io_read_callback(void * ctx, char * buffer, int len) {
|
4
|
+
VALUE io = (VALUE)ctx;
|
5
|
+
VALUE string = rb_funcall(io, rb_intern("read"), 1, INT2NUM(len));
|
6
|
+
|
7
|
+
if(Qnil == string) return 0;
|
8
|
+
|
9
|
+
memcpy(buffer, StringValuePtr(string), (unsigned int)RSTRING_LEN(string));
|
10
|
+
|
11
|
+
return RSTRING_LEN(string);
|
12
|
+
}
|
13
|
+
|
14
|
+
int io_write_callback(void * ctx, char * buffer, int len) {
|
15
|
+
VALUE io = (VALUE)ctx;
|
16
|
+
VALUE string = rb_str_new(buffer, len);
|
17
|
+
|
18
|
+
rb_funcall(io, rb_intern("write"), 1, string);
|
19
|
+
return len;
|
20
|
+
}
|
21
|
+
|
22
|
+
int io_close_callback(void * ctx) {
|
23
|
+
return 0;
|
24
|
+
}
|
@@ -0,0 +1,69 @@
|
|
1
|
+
#include <xml_namespace.h>
|
2
|
+
|
3
|
+
VALUE cNokogiriXmlNamespace ;
|
4
|
+
|
5
|
+
/*
|
6
|
+
* call-seq:
|
7
|
+
* prefix
|
8
|
+
*
|
9
|
+
* Get the prefix for this namespace. Returns +nil+ if there is no prefix.
|
10
|
+
*/
|
11
|
+
static VALUE prefix(VALUE self)
|
12
|
+
{
|
13
|
+
xmlNsPtr ns;
|
14
|
+
xmlDocPtr doc;
|
15
|
+
|
16
|
+
Data_Get_Struct(self, xmlNs, ns);
|
17
|
+
if(!ns->prefix) return Qnil;
|
18
|
+
|
19
|
+
Data_Get_Struct(rb_iv_get(self, "@document"), xmlDoc, doc);
|
20
|
+
|
21
|
+
return NOKOGIRI_STR_NEW2(ns->prefix, doc->encoding);
|
22
|
+
}
|
23
|
+
|
24
|
+
/*
|
25
|
+
* call-seq:
|
26
|
+
* href
|
27
|
+
*
|
28
|
+
* Get the href for this namespace
|
29
|
+
*/
|
30
|
+
static VALUE href(VALUE self)
|
31
|
+
{
|
32
|
+
xmlNsPtr ns;
|
33
|
+
xmlDocPtr doc;
|
34
|
+
|
35
|
+
Data_Get_Struct(self, xmlNs, ns);
|
36
|
+
if(!ns->href) return Qnil;
|
37
|
+
|
38
|
+
Data_Get_Struct(rb_iv_get(self, "@document"), xmlDoc, doc);
|
39
|
+
|
40
|
+
return NOKOGIRI_STR_NEW2(ns->href, doc->encoding);
|
41
|
+
}
|
42
|
+
|
43
|
+
VALUE Nokogiri_wrap_xml_namespace(xmlDocPtr doc, xmlNsPtr node)
|
44
|
+
{
|
45
|
+
assert(doc->_private);
|
46
|
+
|
47
|
+
if(node->_private)
|
48
|
+
return (VALUE)node->_private;
|
49
|
+
|
50
|
+
VALUE ns = Data_Wrap_Struct(cNokogiriXmlNamespace, 0, 0, node);
|
51
|
+
|
52
|
+
rb_iv_set(ns, "@document", DOC_RUBY_OBJECT(doc));
|
53
|
+
|
54
|
+
node->_private = (void *)ns;
|
55
|
+
|
56
|
+
return ns;
|
57
|
+
}
|
58
|
+
|
59
|
+
void init_xml_namespace()
|
60
|
+
{
|
61
|
+
VALUE nokogiri = rb_define_module("Nokogiri");
|
62
|
+
VALUE xml = rb_define_module_under(nokogiri, "XML");
|
63
|
+
VALUE klass = rb_define_class_under(xml, "Namespace", rb_cObject);
|
64
|
+
|
65
|
+
cNokogiriXmlNamespace = klass;
|
66
|
+
|
67
|
+
rb_define_method(klass, "prefix", prefix, 0);
|
68
|
+
rb_define_method(klass, "href", href, 0);
|
69
|
+
}
|
@@ -0,0 +1,928 @@
|
|
1
|
+
#include <xml_node.h>
|
2
|
+
|
3
|
+
#ifdef DEBUG
|
4
|
+
static void debug_node_dealloc(xmlNodePtr x)
|
5
|
+
{
|
6
|
+
NOKOGIRI_DEBUG_START(x)
|
7
|
+
NOKOGIRI_DEBUG_END(x)
|
8
|
+
}
|
9
|
+
#else
|
10
|
+
# define debug_node_dealloc 0
|
11
|
+
#endif
|
12
|
+
|
13
|
+
static void mark(xmlNodePtr node)
|
14
|
+
{
|
15
|
+
rb_gc_mark(DOC_RUBY_OBJECT(node->doc));
|
16
|
+
}
|
17
|
+
|
18
|
+
/* :nodoc: */
|
19
|
+
typedef xmlNodePtr (*node_other_func)(xmlNodePtr, xmlNodePtr);
|
20
|
+
|
21
|
+
/* :nodoc: */
|
22
|
+
static void relink_namespace(xmlNodePtr reparented)
|
23
|
+
{
|
24
|
+
// Make sure that our reparented node has the correct namespaces
|
25
|
+
if(reparented->doc != (xmlDocPtr)reparented->parent)
|
26
|
+
xmlSetNs(reparented, reparented->parent->ns);
|
27
|
+
|
28
|
+
// Search our parents for an existing definition
|
29
|
+
if(reparented->nsDef) {
|
30
|
+
xmlNsPtr ns = xmlSearchNsByHref(
|
31
|
+
reparented->doc,
|
32
|
+
reparented->parent,
|
33
|
+
reparented->nsDef->href
|
34
|
+
);
|
35
|
+
if(ns && ns != reparented->nsDef) reparented->nsDef = NULL;
|
36
|
+
}
|
37
|
+
|
38
|
+
// Only walk all children if there actually is a namespace we need to
|
39
|
+
// reparent.
|
40
|
+
if(NULL == reparented->ns) return;
|
41
|
+
|
42
|
+
// When a node gets reparented, walk it's children to make sure that
|
43
|
+
// their namespaces are reparented as well.
|
44
|
+
xmlNodePtr child = reparented->children;
|
45
|
+
while(NULL != child) {
|
46
|
+
relink_namespace(child);
|
47
|
+
child = child->next;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
/* :nodoc: */
|
52
|
+
static VALUE reparent_node_with(VALUE node_obj, VALUE other_obj, node_other_func func)
|
53
|
+
{
|
54
|
+
VALUE reparented_obj ;
|
55
|
+
xmlNodePtr node, other, reparented ;
|
56
|
+
|
57
|
+
if(! rb_funcall(node_obj, rb_intern("is_a?"), 1, cNokogiriXmlNode))
|
58
|
+
rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node");
|
59
|
+
|
60
|
+
Data_Get_Struct(node_obj, xmlNode, node);
|
61
|
+
Data_Get_Struct(other_obj, xmlNode, other);
|
62
|
+
|
63
|
+
if (node->doc == other->doc) {
|
64
|
+
xmlUnlinkNode(node) ;
|
65
|
+
if ( node->type == XML_TEXT_NODE
|
66
|
+
&& other->type == XML_TEXT_NODE
|
67
|
+
&& is_2_6_16() ) {
|
68
|
+
other->content = xmlStrdup(other->content); // we'd rather leak than segfault.
|
69
|
+
}
|
70
|
+
|
71
|
+
if(!(reparented = (*func)(other, node))) {
|
72
|
+
rb_raise(rb_eRuntimeError, "Could not reparent node (1)");
|
73
|
+
}
|
74
|
+
|
75
|
+
} else {
|
76
|
+
xmlNodePtr duped_node ;
|
77
|
+
// recursively copy to the new document
|
78
|
+
if (!(duped_node = xmlDocCopyNode(node, other->doc, 1))) {
|
79
|
+
rb_raise(rb_eRuntimeError, "Could not reparent node (xmlDocCopyNode)");
|
80
|
+
}
|
81
|
+
if(!(reparented = (*func)(other, duped_node))) {
|
82
|
+
rb_raise(rb_eRuntimeError, "Could not reparent node (2)");
|
83
|
+
}
|
84
|
+
xmlUnlinkNode(node);
|
85
|
+
NOKOGIRI_ROOT_NODE(node);
|
86
|
+
}
|
87
|
+
|
88
|
+
// the child was a text node that was coalesced. we need to have the object
|
89
|
+
// point at SOMETHING, or we'll totally bomb out.
|
90
|
+
if (reparented != node) {
|
91
|
+
DATA_PTR(node_obj) = reparented ;
|
92
|
+
}
|
93
|
+
|
94
|
+
// Appropriately link in namespaces
|
95
|
+
relink_namespace(reparented);
|
96
|
+
|
97
|
+
reparented_obj = Nokogiri_wrap_xml_node(Qnil, reparented);
|
98
|
+
|
99
|
+
rb_funcall(reparented_obj, rb_intern("decorate!"), 0);
|
100
|
+
|
101
|
+
return reparented_obj ;
|
102
|
+
}
|
103
|
+
|
104
|
+
|
105
|
+
/*
|
106
|
+
* call-seq:
|
107
|
+
* document
|
108
|
+
*
|
109
|
+
* Get the document for this Node
|
110
|
+
*/
|
111
|
+
static VALUE document(VALUE self)
|
112
|
+
{
|
113
|
+
xmlNodePtr node;
|
114
|
+
Data_Get_Struct(self, xmlNode, node);
|
115
|
+
return DOC_RUBY_OBJECT(node->doc);
|
116
|
+
}
|
117
|
+
|
118
|
+
/*
|
119
|
+
* call-seq:
|
120
|
+
* pointer_id
|
121
|
+
*
|
122
|
+
* Get the internal pointer number
|
123
|
+
*/
|
124
|
+
static VALUE pointer_id(VALUE self)
|
125
|
+
{
|
126
|
+
xmlNodePtr node;
|
127
|
+
Data_Get_Struct(self, xmlNode, node);
|
128
|
+
|
129
|
+
return INT2NUM((int)(node));
|
130
|
+
}
|
131
|
+
|
132
|
+
/*
|
133
|
+
* call-seq:
|
134
|
+
* encode_special_chars(string)
|
135
|
+
*
|
136
|
+
* Encode any special characters in +string+
|
137
|
+
*/
|
138
|
+
static VALUE encode_special_chars(VALUE self, VALUE string)
|
139
|
+
{
|
140
|
+
xmlNodePtr node;
|
141
|
+
Data_Get_Struct(self, xmlNode, node);
|
142
|
+
xmlChar * encoded = xmlEncodeSpecialChars(
|
143
|
+
node->doc,
|
144
|
+
(const xmlChar *)StringValuePtr(string)
|
145
|
+
);
|
146
|
+
|
147
|
+
VALUE encoded_str = NOKOGIRI_STR_NEW2(encoded, node->doc->encoding);
|
148
|
+
xmlFree(encoded);
|
149
|
+
|
150
|
+
return encoded_str;
|
151
|
+
}
|
152
|
+
|
153
|
+
/*
|
154
|
+
* call-seq:
|
155
|
+
* internal_subset
|
156
|
+
*
|
157
|
+
* Get the internal subset
|
158
|
+
*/
|
159
|
+
static VALUE internal_subset(VALUE self)
|
160
|
+
{
|
161
|
+
xmlNodePtr node;
|
162
|
+
xmlDocPtr doc;
|
163
|
+
Data_Get_Struct(self, xmlNode, node);
|
164
|
+
|
165
|
+
if(!node->doc) return Qnil;
|
166
|
+
|
167
|
+
doc = node->doc;
|
168
|
+
xmlDtdPtr dtd = xmlGetIntSubset(doc);
|
169
|
+
|
170
|
+
if(!dtd) return Qnil;
|
171
|
+
|
172
|
+
return Nokogiri_wrap_xml_node(Qnil, (xmlNodePtr)dtd);
|
173
|
+
}
|
174
|
+
|
175
|
+
/*
|
176
|
+
* call-seq:
|
177
|
+
* dup
|
178
|
+
*
|
179
|
+
* Copy this node. An optional depth may be passed in, but it defaults
|
180
|
+
* to a deep copy. 0 is a shallow copy, 1 is a deep copy.
|
181
|
+
*/
|
182
|
+
static VALUE duplicate_node(int argc, VALUE *argv, VALUE self)
|
183
|
+
{
|
184
|
+
VALUE level;
|
185
|
+
|
186
|
+
if(rb_scan_args(argc, argv, "01", &level) == 0)
|
187
|
+
level = INT2NUM(1);
|
188
|
+
|
189
|
+
xmlNodePtr node, dup;
|
190
|
+
Data_Get_Struct(self, xmlNode, node);
|
191
|
+
|
192
|
+
dup = xmlDocCopyNode(node, node->doc, NUM2INT(level));
|
193
|
+
if(dup == NULL) return Qnil;
|
194
|
+
|
195
|
+
return Nokogiri_wrap_xml_node(rb_obj_class(self), dup);
|
196
|
+
}
|
197
|
+
|
198
|
+
/*
|
199
|
+
* call-seq:
|
200
|
+
* unlink
|
201
|
+
*
|
202
|
+
* Unlink this node from its current context.
|
203
|
+
*/
|
204
|
+
static VALUE unlink_node(VALUE self)
|
205
|
+
{
|
206
|
+
xmlNodePtr node;
|
207
|
+
Data_Get_Struct(self, xmlNode, node);
|
208
|
+
xmlUnlinkNode(node);
|
209
|
+
NOKOGIRI_ROOT_NODE(node);
|
210
|
+
return self;
|
211
|
+
}
|
212
|
+
|
213
|
+
/*
|
214
|
+
* call-seq:
|
215
|
+
* blank?
|
216
|
+
*
|
217
|
+
* Is this node blank?
|
218
|
+
*/
|
219
|
+
static VALUE blank_eh(VALUE self)
|
220
|
+
{
|
221
|
+
xmlNodePtr node;
|
222
|
+
Data_Get_Struct(self, xmlNode, node);
|
223
|
+
if(1 == xmlIsBlankNode(node))
|
224
|
+
return Qtrue;
|
225
|
+
return Qfalse;
|
226
|
+
}
|
227
|
+
|
228
|
+
/*
|
229
|
+
* call-seq:
|
230
|
+
* next_sibling
|
231
|
+
*
|
232
|
+
* Returns the next sibling node
|
233
|
+
*/
|
234
|
+
static VALUE next_sibling(VALUE self)
|
235
|
+
{
|
236
|
+
xmlNodePtr node, sibling;
|
237
|
+
Data_Get_Struct(self, xmlNode, node);
|
238
|
+
|
239
|
+
sibling = node->next;
|
240
|
+
if(!sibling) return Qnil;
|
241
|
+
|
242
|
+
return Nokogiri_wrap_xml_node(Qnil, sibling) ;
|
243
|
+
}
|
244
|
+
|
245
|
+
/*
|
246
|
+
* call-seq:
|
247
|
+
* previous_sibling
|
248
|
+
*
|
249
|
+
* Returns the previous sibling node
|
250
|
+
*/
|
251
|
+
static VALUE previous_sibling(VALUE self)
|
252
|
+
{
|
253
|
+
xmlNodePtr node, sibling;
|
254
|
+
Data_Get_Struct(self, xmlNode, node);
|
255
|
+
|
256
|
+
sibling = node->prev;
|
257
|
+
if(!sibling) return Qnil;
|
258
|
+
|
259
|
+
return Nokogiri_wrap_xml_node(Qnil, sibling);
|
260
|
+
}
|
261
|
+
|
262
|
+
/* :nodoc: */
|
263
|
+
static VALUE replace(VALUE self, VALUE _new_node)
|
264
|
+
{
|
265
|
+
xmlNodePtr node, new_node;
|
266
|
+
Data_Get_Struct(self, xmlNode, node);
|
267
|
+
Data_Get_Struct(_new_node, xmlNode, new_node);
|
268
|
+
|
269
|
+
xmlReplaceNode(node, new_node);
|
270
|
+
|
271
|
+
// Appropriately link in namespaces
|
272
|
+
relink_namespace(new_node);
|
273
|
+
return self ;
|
274
|
+
}
|
275
|
+
|
276
|
+
/*
|
277
|
+
* call-seq:
|
278
|
+
* children
|
279
|
+
*
|
280
|
+
* Get the list of children for this node as a NodeSet
|
281
|
+
*/
|
282
|
+
static VALUE children(VALUE self)
|
283
|
+
{
|
284
|
+
xmlNodePtr node;
|
285
|
+
Data_Get_Struct(self, xmlNode, node);
|
286
|
+
|
287
|
+
xmlNodePtr child = node->children;
|
288
|
+
xmlNodeSetPtr set = xmlXPathNodeSetCreate(child);
|
289
|
+
|
290
|
+
if(!child) return Nokogiri_wrap_xml_node_set(set);
|
291
|
+
|
292
|
+
child = child->next;
|
293
|
+
while(NULL != child) {
|
294
|
+
xmlXPathNodeSetAdd(set, child);
|
295
|
+
child = child->next;
|
296
|
+
}
|
297
|
+
|
298
|
+
VALUE node_set = Nokogiri_wrap_xml_node_set(set);
|
299
|
+
rb_iv_set(node_set, "@document", DOC_RUBY_OBJECT(node->doc));
|
300
|
+
|
301
|
+
return node_set;
|
302
|
+
}
|
303
|
+
|
304
|
+
/*
|
305
|
+
* call-seq:
|
306
|
+
* child
|
307
|
+
*
|
308
|
+
* Returns the child node
|
309
|
+
*/
|
310
|
+
static VALUE child(VALUE self)
|
311
|
+
{
|
312
|
+
xmlNodePtr node, child;
|
313
|
+
Data_Get_Struct(self, xmlNode, node);
|
314
|
+
|
315
|
+
child = node->children;
|
316
|
+
if(!child) return Qnil;
|
317
|
+
|
318
|
+
return Nokogiri_wrap_xml_node(Qnil, child);
|
319
|
+
}
|
320
|
+
|
321
|
+
/*
|
322
|
+
* call-seq:
|
323
|
+
* key?(attribute)
|
324
|
+
*
|
325
|
+
* Returns true if +attribute+ is set
|
326
|
+
*/
|
327
|
+
static VALUE key_eh(VALUE self, VALUE attribute)
|
328
|
+
{
|
329
|
+
xmlNodePtr node;
|
330
|
+
Data_Get_Struct(self, xmlNode, node);
|
331
|
+
if(xmlHasProp(node, (xmlChar *)StringValuePtr(attribute)))
|
332
|
+
return Qtrue;
|
333
|
+
return Qfalse;
|
334
|
+
}
|
335
|
+
|
336
|
+
/*
|
337
|
+
* call-seq:
|
338
|
+
* namespaced_key?(attribute, namespace)
|
339
|
+
*
|
340
|
+
* Returns true if +attribute+ is set with +namespace+
|
341
|
+
*/
|
342
|
+
static VALUE namespaced_key_eh(VALUE self, VALUE attribute, VALUE namespace)
|
343
|
+
{
|
344
|
+
xmlNodePtr node;
|
345
|
+
Data_Get_Struct(self, xmlNode, node);
|
346
|
+
if(xmlHasNsProp(node, (xmlChar *)StringValuePtr(attribute),
|
347
|
+
Qnil == namespace ? NULL : (xmlChar *)StringValuePtr(namespace)))
|
348
|
+
return Qtrue;
|
349
|
+
return Qfalse;
|
350
|
+
}
|
351
|
+
|
352
|
+
/*
|
353
|
+
* call-seq:
|
354
|
+
* []=(property, value)
|
355
|
+
*
|
356
|
+
* Set the +property+ to +value+
|
357
|
+
*/
|
358
|
+
static VALUE set(VALUE self, VALUE property, VALUE value)
|
359
|
+
{
|
360
|
+
xmlNodePtr node;
|
361
|
+
Data_Get_Struct(self, xmlNode, node);
|
362
|
+
|
363
|
+
xmlSetProp(node, (xmlChar *)StringValuePtr(property),
|
364
|
+
(xmlChar *)StringValuePtr(value));
|
365
|
+
|
366
|
+
return value;
|
367
|
+
}
|
368
|
+
|
369
|
+
/*
|
370
|
+
* call-seq:
|
371
|
+
* get(attribute)
|
372
|
+
*
|
373
|
+
* Get the value for +attribute+
|
374
|
+
*/
|
375
|
+
static VALUE get(VALUE self, VALUE attribute)
|
376
|
+
{
|
377
|
+
xmlNodePtr node;
|
378
|
+
xmlChar* propstr ;
|
379
|
+
VALUE rval ;
|
380
|
+
Data_Get_Struct(self, xmlNode, node);
|
381
|
+
|
382
|
+
if(attribute == Qnil) return Qnil;
|
383
|
+
|
384
|
+
propstr = xmlGetProp(node, (xmlChar *)StringValuePtr(attribute));
|
385
|
+
|
386
|
+
if(NULL == propstr) return Qnil;
|
387
|
+
|
388
|
+
rval = NOKOGIRI_STR_NEW2(propstr, node->doc->encoding);
|
389
|
+
|
390
|
+
xmlFree(propstr);
|
391
|
+
return rval ;
|
392
|
+
}
|
393
|
+
|
394
|
+
/*
|
395
|
+
* call-seq:
|
396
|
+
* set_namespace(namespace)
|
397
|
+
*
|
398
|
+
* Set the namespace to +namespace+
|
399
|
+
*/
|
400
|
+
static VALUE set_namespace(VALUE self, VALUE namespace)
|
401
|
+
{
|
402
|
+
xmlNodePtr node;
|
403
|
+
xmlNsPtr ns;
|
404
|
+
|
405
|
+
Data_Get_Struct(self, xmlNode, node);
|
406
|
+
Data_Get_Struct(namespace, xmlNs, ns);
|
407
|
+
|
408
|
+
xmlSetNs(node, ns);
|
409
|
+
|
410
|
+
return self;
|
411
|
+
}
|
412
|
+
|
413
|
+
/*
|
414
|
+
* call-seq:
|
415
|
+
* attribute(name)
|
416
|
+
*
|
417
|
+
* Get the attribute node with +name+
|
418
|
+
*/
|
419
|
+
static VALUE attr(VALUE self, VALUE name)
|
420
|
+
{
|
421
|
+
xmlNodePtr node;
|
422
|
+
xmlAttrPtr prop;
|
423
|
+
Data_Get_Struct(self, xmlNode, node);
|
424
|
+
prop = xmlHasProp(node, (xmlChar *)StringValuePtr(name));
|
425
|
+
|
426
|
+
if(! prop) return Qnil;
|
427
|
+
return Nokogiri_wrap_xml_node(Qnil, (xmlNodePtr)prop);
|
428
|
+
}
|
429
|
+
|
430
|
+
/*
|
431
|
+
* call-seq:
|
432
|
+
* attribute_with_ns(name, namespace)
|
433
|
+
*
|
434
|
+
* Get the attribute node with +name+ and +namespace+
|
435
|
+
*/
|
436
|
+
static VALUE attribute_with_ns(VALUE self, VALUE name, VALUE namespace)
|
437
|
+
{
|
438
|
+
xmlNodePtr node;
|
439
|
+
xmlAttrPtr prop;
|
440
|
+
Data_Get_Struct(self, xmlNode, node);
|
441
|
+
prop = xmlHasNsProp(node, (xmlChar *)StringValuePtr(name),
|
442
|
+
Qnil == namespace ? NULL : (xmlChar *)StringValuePtr(namespace));
|
443
|
+
|
444
|
+
if(! prop) return Qnil;
|
445
|
+
return Nokogiri_wrap_xml_node(Qnil, (xmlNodePtr)prop);
|
446
|
+
}
|
447
|
+
|
448
|
+
/*
|
449
|
+
* call-seq:
|
450
|
+
* attribute_nodes()
|
451
|
+
*
|
452
|
+
* returns a list containing the Node attributes.
|
453
|
+
*/
|
454
|
+
static VALUE attribute_nodes(VALUE self)
|
455
|
+
{
|
456
|
+
/* this code in the mode of xmlHasProp() */
|
457
|
+
xmlNodePtr node ;
|
458
|
+
VALUE attr ;
|
459
|
+
|
460
|
+
attr = rb_ary_new() ;
|
461
|
+
Data_Get_Struct(self, xmlNode, node);
|
462
|
+
|
463
|
+
Nokogiri_xml_node_properties(node, attr);
|
464
|
+
|
465
|
+
return attr ;
|
466
|
+
}
|
467
|
+
|
468
|
+
|
469
|
+
/*
|
470
|
+
* call-seq:
|
471
|
+
* namespace()
|
472
|
+
*
|
473
|
+
* returns the Nokogiri::XML::Namespace for the node, if one exists.
|
474
|
+
*/
|
475
|
+
static VALUE namespace(VALUE self)
|
476
|
+
{
|
477
|
+
xmlNodePtr node ;
|
478
|
+
Data_Get_Struct(self, xmlNode, node);
|
479
|
+
|
480
|
+
if (node->ns)
|
481
|
+
return Nokogiri_wrap_xml_namespace(node->doc, node->ns);
|
482
|
+
|
483
|
+
return Qnil ;
|
484
|
+
}
|
485
|
+
|
486
|
+
/*
|
487
|
+
* call-seq:
|
488
|
+
* namespace_definitions()
|
489
|
+
*
|
490
|
+
* returns a list of Namespace nodes defined on _self_
|
491
|
+
*/
|
492
|
+
static VALUE namespace_definitions(VALUE self)
|
493
|
+
{
|
494
|
+
/* this code in the mode of xmlHasProp() */
|
495
|
+
xmlNodePtr node ;
|
496
|
+
|
497
|
+
Data_Get_Struct(self, xmlNode, node);
|
498
|
+
|
499
|
+
VALUE list = rb_ary_new();
|
500
|
+
|
501
|
+
xmlNsPtr ns = node->nsDef;
|
502
|
+
|
503
|
+
if(!ns) return list;
|
504
|
+
|
505
|
+
while(NULL != ns) {
|
506
|
+
rb_ary_push(list, Nokogiri_wrap_xml_namespace(node->doc, ns));
|
507
|
+
ns = ns->next;
|
508
|
+
}
|
509
|
+
|
510
|
+
return list;
|
511
|
+
}
|
512
|
+
|
513
|
+
/*
|
514
|
+
* call-seq:
|
515
|
+
* node_type
|
516
|
+
*
|
517
|
+
* Get the type for this Node
|
518
|
+
*/
|
519
|
+
static VALUE node_type(VALUE self)
|
520
|
+
{
|
521
|
+
xmlNodePtr node;
|
522
|
+
Data_Get_Struct(self, xmlNode, node);
|
523
|
+
return INT2NUM((int)node->type);
|
524
|
+
}
|
525
|
+
|
526
|
+
/*
|
527
|
+
* call-seq:
|
528
|
+
* content=
|
529
|
+
*
|
530
|
+
* Set the content for this Node
|
531
|
+
*/
|
532
|
+
static VALUE set_content(VALUE self, VALUE content)
|
533
|
+
{
|
534
|
+
xmlNodePtr node;
|
535
|
+
Data_Get_Struct(self, xmlNode, node);
|
536
|
+
xmlNodeSetContent(node, (xmlChar *)StringValuePtr(content));
|
537
|
+
return content;
|
538
|
+
}
|
539
|
+
|
540
|
+
/*
|
541
|
+
* call-seq:
|
542
|
+
* content
|
543
|
+
*
|
544
|
+
* Returns the content for this Node
|
545
|
+
*/
|
546
|
+
static VALUE get_content(VALUE self)
|
547
|
+
{
|
548
|
+
xmlNodePtr node;
|
549
|
+
Data_Get_Struct(self, xmlNode, node);
|
550
|
+
|
551
|
+
xmlChar * content = xmlNodeGetContent(node);
|
552
|
+
if(content) {
|
553
|
+
VALUE rval = NOKOGIRI_STR_NEW2(content, node->doc->encoding);
|
554
|
+
xmlFree(content);
|
555
|
+
return rval;
|
556
|
+
}
|
557
|
+
return Qnil;
|
558
|
+
}
|
559
|
+
|
560
|
+
/*
|
561
|
+
* call-seq:
|
562
|
+
* add_child(node)
|
563
|
+
*
|
564
|
+
* Add +node+ as a child of this node. Returns the new child node.
|
565
|
+
*/
|
566
|
+
static VALUE add_child(VALUE self, VALUE child)
|
567
|
+
{
|
568
|
+
return reparent_node_with(child, self, xmlAddChild);
|
569
|
+
}
|
570
|
+
|
571
|
+
/*
|
572
|
+
* call-seq:
|
573
|
+
* parent
|
574
|
+
*
|
575
|
+
* Get the parent Node for this Node
|
576
|
+
*/
|
577
|
+
static VALUE get_parent(VALUE self)
|
578
|
+
{
|
579
|
+
xmlNodePtr node, parent;
|
580
|
+
Data_Get_Struct(self, xmlNode, node);
|
581
|
+
|
582
|
+
parent = node->parent;
|
583
|
+
if(!parent) return Qnil;
|
584
|
+
|
585
|
+
return Nokogiri_wrap_xml_node(Qnil, parent) ;
|
586
|
+
}
|
587
|
+
|
588
|
+
/*
|
589
|
+
* call-seq:
|
590
|
+
* name=(new_name)
|
591
|
+
*
|
592
|
+
* Set the name for this Node
|
593
|
+
*/
|
594
|
+
static VALUE set_name(VALUE self, VALUE new_name)
|
595
|
+
{
|
596
|
+
xmlNodePtr node;
|
597
|
+
Data_Get_Struct(self, xmlNode, node);
|
598
|
+
xmlNodeSetName(node, (xmlChar*)StringValuePtr(new_name));
|
599
|
+
return new_name;
|
600
|
+
}
|
601
|
+
|
602
|
+
/*
|
603
|
+
* call-seq:
|
604
|
+
* name
|
605
|
+
*
|
606
|
+
* Returns the name for this Node
|
607
|
+
*/
|
608
|
+
static VALUE get_name(VALUE self)
|
609
|
+
{
|
610
|
+
xmlNodePtr node;
|
611
|
+
Data_Get_Struct(self, xmlNode, node);
|
612
|
+
if(node->name)
|
613
|
+
return NOKOGIRI_STR_NEW2(node->name, node->doc->encoding);
|
614
|
+
return Qnil;
|
615
|
+
}
|
616
|
+
|
617
|
+
/*
|
618
|
+
* call-seq:
|
619
|
+
* path
|
620
|
+
*
|
621
|
+
* Returns the path associated with this Node
|
622
|
+
*/
|
623
|
+
static VALUE path(VALUE self)
|
624
|
+
{
|
625
|
+
xmlNodePtr node;
|
626
|
+
xmlChar *path ;
|
627
|
+
Data_Get_Struct(self, xmlNode, node);
|
628
|
+
|
629
|
+
path = xmlGetNodePath(node);
|
630
|
+
VALUE rval = NOKOGIRI_STR_NEW2(path, node->doc->encoding);
|
631
|
+
xmlFree(path);
|
632
|
+
return rval ;
|
633
|
+
}
|
634
|
+
|
635
|
+
/*
|
636
|
+
* call-seq:
|
637
|
+
* add_next_sibling(node)
|
638
|
+
*
|
639
|
+
* Insert +node+ after this node (as a sibling).
|
640
|
+
*/
|
641
|
+
static VALUE add_next_sibling(VALUE self, VALUE rb_node)
|
642
|
+
{
|
643
|
+
return reparent_node_with(rb_node, self, xmlAddNextSibling) ;
|
644
|
+
}
|
645
|
+
|
646
|
+
/*
|
647
|
+
* call-seq:
|
648
|
+
* add_previous_sibling(node)
|
649
|
+
*
|
650
|
+
* Insert +node+ before this node (as a sibling).
|
651
|
+
*/
|
652
|
+
static VALUE add_previous_sibling(VALUE self, VALUE rb_node)
|
653
|
+
{
|
654
|
+
return reparent_node_with(rb_node, self, xmlAddPrevSibling) ;
|
655
|
+
}
|
656
|
+
|
657
|
+
/*
|
658
|
+
* call-seq:
|
659
|
+
* native_write_to(io, encoding, options)
|
660
|
+
*
|
661
|
+
* Write this Node to +io+ with +encoding+ and +options+
|
662
|
+
*/
|
663
|
+
static VALUE native_write_to(
|
664
|
+
VALUE self,
|
665
|
+
VALUE io,
|
666
|
+
VALUE encoding,
|
667
|
+
VALUE indent_string,
|
668
|
+
VALUE options
|
669
|
+
) {
|
670
|
+
xmlNodePtr node;
|
671
|
+
|
672
|
+
Data_Get_Struct(self, xmlNode, node);
|
673
|
+
|
674
|
+
xmlIndentTreeOutput = 1;
|
675
|
+
|
676
|
+
xmlTreeIndentString = StringValuePtr(indent_string);
|
677
|
+
|
678
|
+
xmlSaveCtxtPtr savectx = xmlSaveToIO(
|
679
|
+
(xmlOutputWriteCallback)io_write_callback,
|
680
|
+
(xmlOutputCloseCallback)io_close_callback,
|
681
|
+
(void *)io,
|
682
|
+
RTEST(encoding) ? StringValuePtr(encoding) : NULL,
|
683
|
+
NUM2INT(options)
|
684
|
+
);
|
685
|
+
|
686
|
+
xmlSaveTree(savectx, node);
|
687
|
+
xmlSaveClose(savectx);
|
688
|
+
return io;
|
689
|
+
}
|
690
|
+
|
691
|
+
/*
|
692
|
+
* call-seq:
|
693
|
+
* line
|
694
|
+
*
|
695
|
+
* Returns the line for this Node
|
696
|
+
*/
|
697
|
+
static VALUE line(VALUE self)
|
698
|
+
{
|
699
|
+
xmlNodePtr node;
|
700
|
+
Data_Get_Struct(self, xmlNode, node);
|
701
|
+
|
702
|
+
return INT2NUM(node->line);
|
703
|
+
}
|
704
|
+
|
705
|
+
/*
|
706
|
+
* call-seq:
|
707
|
+
* add_namespace_definition(prefix, href)
|
708
|
+
*
|
709
|
+
* Adds a namespace definition with +prefix+ using +href+
|
710
|
+
*/
|
711
|
+
static VALUE add_namespace_definition(VALUE self, VALUE prefix, VALUE href)
|
712
|
+
{
|
713
|
+
xmlNodePtr node;
|
714
|
+
Data_Get_Struct(self, xmlNode, node);
|
715
|
+
|
716
|
+
|
717
|
+
xmlNsPtr ns = xmlNewNs(
|
718
|
+
node,
|
719
|
+
(const xmlChar *)StringValuePtr(href),
|
720
|
+
(const xmlChar *)(prefix == Qnil ? NULL : StringValuePtr(prefix))
|
721
|
+
);
|
722
|
+
|
723
|
+
if(Qnil == prefix) xmlSetNs(node, ns);
|
724
|
+
|
725
|
+
return Nokogiri_wrap_xml_namespace(node->doc, ns);
|
726
|
+
}
|
727
|
+
|
728
|
+
/*
|
729
|
+
* call-seq:
|
730
|
+
* new(name, document)
|
731
|
+
*
|
732
|
+
* Create a new node with +name+ sharing GC lifecycle with +document+
|
733
|
+
*/
|
734
|
+
static VALUE new(int argc, VALUE *argv, VALUE klass)
|
735
|
+
{
|
736
|
+
xmlDocPtr doc;
|
737
|
+
VALUE name;
|
738
|
+
VALUE document;
|
739
|
+
VALUE rest;
|
740
|
+
|
741
|
+
rb_scan_args(argc, argv, "2*", &name, &document, &rest);
|
742
|
+
|
743
|
+
Data_Get_Struct(document, xmlDoc, doc);
|
744
|
+
|
745
|
+
xmlNodePtr node = xmlNewNode(NULL, (xmlChar *)StringValuePtr(name));
|
746
|
+
node->doc = doc->doc;
|
747
|
+
NOKOGIRI_ROOT_NODE(node);
|
748
|
+
|
749
|
+
VALUE rb_node = Nokogiri_wrap_xml_node(klass, node);
|
750
|
+
rb_funcall2(rb_node, rb_intern("initialize"), argc, argv);
|
751
|
+
|
752
|
+
if(rb_block_given_p()) rb_yield(rb_node);
|
753
|
+
|
754
|
+
return rb_node;
|
755
|
+
}
|
756
|
+
|
757
|
+
/*
|
758
|
+
* call-seq:
|
759
|
+
* dump_html
|
760
|
+
*
|
761
|
+
* Returns the Node as html.
|
762
|
+
*/
|
763
|
+
static VALUE dump_html(VALUE self)
|
764
|
+
{
|
765
|
+
xmlBufferPtr buf ;
|
766
|
+
xmlNodePtr node ;
|
767
|
+
Data_Get_Struct(self, xmlNode, node);
|
768
|
+
|
769
|
+
if(node->doc->type == XML_DOCUMENT_NODE)
|
770
|
+
return rb_funcall(self, rb_intern("to_xml"), 0);
|
771
|
+
|
772
|
+
buf = xmlBufferCreate() ;
|
773
|
+
htmlNodeDump(buf, node->doc, node);
|
774
|
+
VALUE html = NOKOGIRI_STR_NEW2(buf->content, node->doc->encoding);
|
775
|
+
xmlBufferFree(buf);
|
776
|
+
return html ;
|
777
|
+
}
|
778
|
+
|
779
|
+
/*
|
780
|
+
* call-seq:
|
781
|
+
* compare(other)
|
782
|
+
*
|
783
|
+
* Compare this Node to +other+ with respect to their Document
|
784
|
+
*/
|
785
|
+
static VALUE compare(VALUE self, VALUE _other)
|
786
|
+
{
|
787
|
+
xmlNodePtr node, other;
|
788
|
+
Data_Get_Struct(self, xmlNode, node);
|
789
|
+
Data_Get_Struct(_other, xmlNode, other);
|
790
|
+
|
791
|
+
return INT2NUM(xmlXPathCmpNodes(other, node));
|
792
|
+
}
|
793
|
+
|
794
|
+
VALUE Nokogiri_wrap_xml_node(VALUE klass, xmlNodePtr node)
|
795
|
+
{
|
796
|
+
assert(node);
|
797
|
+
|
798
|
+
VALUE document = Qnil ;
|
799
|
+
VALUE node_cache = Qnil ;
|
800
|
+
VALUE rb_node = Qnil ;
|
801
|
+
|
802
|
+
if(node->type == XML_DOCUMENT_NODE || node->type == XML_HTML_DOCUMENT_NODE)
|
803
|
+
return DOC_RUBY_OBJECT(node->doc);
|
804
|
+
|
805
|
+
if(NULL != node->_private) return (VALUE)node->_private;
|
806
|
+
|
807
|
+
if(RTEST(klass))
|
808
|
+
rb_node = Data_Wrap_Struct(klass, mark, debug_node_dealloc, node) ;
|
809
|
+
|
810
|
+
else switch(node->type)
|
811
|
+
{
|
812
|
+
case XML_ELEMENT_NODE:
|
813
|
+
klass = cNokogiriXmlElement;
|
814
|
+
break;
|
815
|
+
case XML_TEXT_NODE:
|
816
|
+
klass = cNokogiriXmlText;
|
817
|
+
break;
|
818
|
+
case XML_ATTRIBUTE_NODE:
|
819
|
+
klass = cNokogiriXmlAttr;
|
820
|
+
break;
|
821
|
+
case XML_ENTITY_REF_NODE:
|
822
|
+
klass = cNokogiriXmlEntityReference;
|
823
|
+
break;
|
824
|
+
case XML_COMMENT_NODE:
|
825
|
+
klass = cNokogiriXmlComment;
|
826
|
+
break;
|
827
|
+
case XML_DOCUMENT_FRAG_NODE:
|
828
|
+
klass = cNokogiriXmlDocumentFragment;
|
829
|
+
break;
|
830
|
+
case XML_PI_NODE:
|
831
|
+
klass = cNokogiriXmlProcessingInstruction;
|
832
|
+
break;
|
833
|
+
case XML_ENTITY_DECL:
|
834
|
+
klass = cNokogiriXmlEntityDeclaration;
|
835
|
+
break;
|
836
|
+
case XML_CDATA_SECTION_NODE:
|
837
|
+
klass = cNokogiriXmlCData;
|
838
|
+
break;
|
839
|
+
case XML_DTD_NODE:
|
840
|
+
klass = rb_const_get(mNokogiriXml, rb_intern("DTD"));
|
841
|
+
break;
|
842
|
+
default:
|
843
|
+
klass = cNokogiriXmlNode;
|
844
|
+
}
|
845
|
+
|
846
|
+
rb_node = Data_Wrap_Struct(klass, mark, debug_node_dealloc, node) ;
|
847
|
+
|
848
|
+
node->_private = (void *)rb_node;
|
849
|
+
|
850
|
+
if (DOC_RUBY_OBJECT_TEST(node->doc) && DOC_RUBY_OBJECT(node->doc)) {
|
851
|
+
document = DOC_RUBY_OBJECT(node->doc);
|
852
|
+
node_cache = rb_iv_get(document, "@node_cache");
|
853
|
+
}
|
854
|
+
|
855
|
+
rb_ary_push(node_cache, rb_node);
|
856
|
+
rb_funcall(document, rb_intern("decorate"), 1, rb_node);
|
857
|
+
|
858
|
+
return rb_node ;
|
859
|
+
}
|
860
|
+
|
861
|
+
|
862
|
+
void Nokogiri_xml_node_properties(xmlNodePtr node, VALUE attr_list)
|
863
|
+
{
|
864
|
+
xmlAttrPtr prop;
|
865
|
+
prop = node->properties ;
|
866
|
+
while (prop != NULL) {
|
867
|
+
rb_ary_push(attr_list, Nokogiri_wrap_xml_node(Qnil, (xmlNodePtr)prop));
|
868
|
+
prop = prop->next ;
|
869
|
+
}
|
870
|
+
}
|
871
|
+
|
872
|
+
VALUE cNokogiriXmlNode ;
|
873
|
+
VALUE cNokogiriXmlElement ;
|
874
|
+
VALUE cNokogiriXmlEntityDeclaration ;
|
875
|
+
|
876
|
+
void init_xml_node()
|
877
|
+
{
|
878
|
+
VALUE nokogiri = rb_define_module("Nokogiri");
|
879
|
+
VALUE xml = rb_define_module_under(nokogiri, "XML");
|
880
|
+
VALUE klass = rb_define_class_under(xml, "Node", rb_cObject);
|
881
|
+
|
882
|
+
cNokogiriXmlNode = klass;
|
883
|
+
|
884
|
+
cNokogiriXmlElement = rb_define_class_under(xml, "Element", klass);
|
885
|
+
cNokogiriXmlEntityDeclaration =
|
886
|
+
rb_define_class_under(xml, "EntityDeclaration", klass);
|
887
|
+
|
888
|
+
rb_define_singleton_method(klass, "new", new, -1);
|
889
|
+
|
890
|
+
rb_define_method(klass, "add_namespace_definition", add_namespace_definition, 2);
|
891
|
+
rb_define_method(klass, "node_name", get_name, 0);
|
892
|
+
rb_define_method(klass, "document", document, 0);
|
893
|
+
rb_define_method(klass, "node_name=", set_name, 1);
|
894
|
+
rb_define_method(klass, "add_child", add_child, 1);
|
895
|
+
rb_define_method(klass, "parent", get_parent, 0);
|
896
|
+
rb_define_method(klass, "child", child, 0);
|
897
|
+
rb_define_method(klass, "children", children, 0);
|
898
|
+
rb_define_method(klass, "next_sibling", next_sibling, 0);
|
899
|
+
rb_define_method(klass, "previous_sibling", previous_sibling, 0);
|
900
|
+
rb_define_method(klass, "node_type", node_type, 0);
|
901
|
+
rb_define_method(klass, "content", get_content, 0);
|
902
|
+
rb_define_method(klass, "path", path, 0);
|
903
|
+
rb_define_method(klass, "key?", key_eh, 1);
|
904
|
+
rb_define_method(klass, "namespaced_key?", namespaced_key_eh, 2);
|
905
|
+
rb_define_method(klass, "blank?", blank_eh, 0);
|
906
|
+
rb_define_method(klass, "[]=", set, 2);
|
907
|
+
rb_define_method(klass, "attribute_nodes", attribute_nodes, 0);
|
908
|
+
rb_define_method(klass, "attribute", attr, 1);
|
909
|
+
rb_define_method(klass, "attribute_with_ns", attribute_with_ns, 2);
|
910
|
+
rb_define_method(klass, "namespace", namespace, 0);
|
911
|
+
rb_define_method(klass, "namespace_definitions", namespace_definitions, 0);
|
912
|
+
rb_define_method(klass, "add_previous_sibling", add_previous_sibling, 1);
|
913
|
+
rb_define_method(klass, "add_next_sibling", add_next_sibling, 1);
|
914
|
+
rb_define_method(klass, "encode_special_chars", encode_special_chars, 1);
|
915
|
+
rb_define_method(klass, "dup", duplicate_node, -1);
|
916
|
+
rb_define_method(klass, "unlink", unlink_node, 0);
|
917
|
+
rb_define_method(klass, "internal_subset", internal_subset, 0);
|
918
|
+
rb_define_method(klass, "pointer_id", pointer_id, 0);
|
919
|
+
rb_define_method(klass, "line", line, 0);
|
920
|
+
|
921
|
+
rb_define_private_method(klass, "dump_html", dump_html, 0);
|
922
|
+
rb_define_private_method(klass, "native_write_to", native_write_to, 4);
|
923
|
+
rb_define_private_method(klass, "replace_with_node", replace, 1);
|
924
|
+
rb_define_private_method(klass, "native_content=", set_content, 1);
|
925
|
+
rb_define_private_method(klass, "get", get, 1);
|
926
|
+
rb_define_private_method(klass, "set_namespace", set_namespace, 1);
|
927
|
+
rb_define_private_method(klass, "compare", compare, 1);
|
928
|
+
}
|