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,14 @@
|
|
1
|
+
#ifndef NOKOGIRI_XML_NODE
|
2
|
+
#define NOKOGIRI_XML_NODE
|
3
|
+
|
4
|
+
#include <nokogiri.h>
|
5
|
+
|
6
|
+
void init_xml_node();
|
7
|
+
|
8
|
+
extern VALUE cNokogiriXmlNode ;
|
9
|
+
extern VALUE cNokogiriXmlElement ;
|
10
|
+
extern VALUE cNokogiriXmlEntityDeclaration ;
|
11
|
+
|
12
|
+
VALUE Nokogiri_wrap_xml_node(VALUE klass, xmlNodePtr node) ;
|
13
|
+
void Nokogiri_xml_node_properties(xmlNodePtr node, VALUE attr_hash) ;
|
14
|
+
#endif
|
@@ -0,0 +1,386 @@
|
|
1
|
+
#include <xml_node_set.h>
|
2
|
+
#include <libxml/xpathInternals.h>
|
3
|
+
|
4
|
+
/*
|
5
|
+
* call-seq:
|
6
|
+
* dup
|
7
|
+
*
|
8
|
+
* Duplicate this node set
|
9
|
+
*/
|
10
|
+
static VALUE duplicate(VALUE self)
|
11
|
+
{
|
12
|
+
xmlNodeSetPtr node_set;
|
13
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
14
|
+
|
15
|
+
xmlNodeSetPtr dupl = xmlXPathNodeSetMerge(NULL, node_set);
|
16
|
+
|
17
|
+
return Nokogiri_wrap_xml_node_set(dupl);
|
18
|
+
}
|
19
|
+
|
20
|
+
/*
|
21
|
+
* call-seq:
|
22
|
+
* length
|
23
|
+
*
|
24
|
+
* Get the length of the node set
|
25
|
+
*/
|
26
|
+
static VALUE length(VALUE self)
|
27
|
+
{
|
28
|
+
xmlNodeSetPtr node_set;
|
29
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
30
|
+
|
31
|
+
if(node_set)
|
32
|
+
return INT2NUM(node_set->nodeNr);
|
33
|
+
|
34
|
+
return INT2NUM(0);
|
35
|
+
}
|
36
|
+
|
37
|
+
/*
|
38
|
+
* call-seq:
|
39
|
+
* push(node)
|
40
|
+
*
|
41
|
+
* Append +node+ to the NodeSet.
|
42
|
+
*/
|
43
|
+
static VALUE push(VALUE self, VALUE rb_node)
|
44
|
+
{
|
45
|
+
xmlNodeSetPtr node_set;
|
46
|
+
xmlNodePtr node;
|
47
|
+
|
48
|
+
if(! rb_funcall(rb_node, rb_intern("is_a?"), 1, cNokogiriXmlNode))
|
49
|
+
rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node");
|
50
|
+
|
51
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
52
|
+
Data_Get_Struct(rb_node, xmlNode, node);
|
53
|
+
xmlXPathNodeSetAdd(node_set, node);
|
54
|
+
return self;
|
55
|
+
}
|
56
|
+
|
57
|
+
/*
|
58
|
+
* call-seq:
|
59
|
+
* delete(node)
|
60
|
+
*
|
61
|
+
* Delete +node+ from the Nodeset, if it is a member. Returns the deleted node
|
62
|
+
* if found, otherwise returns nil.
|
63
|
+
*/
|
64
|
+
static VALUE delete(VALUE self, VALUE rb_node)
|
65
|
+
{
|
66
|
+
xmlNodeSetPtr node_set ;
|
67
|
+
xmlNodePtr node ;
|
68
|
+
|
69
|
+
if(! rb_funcall(rb_node, rb_intern("is_a?"), 1, cNokogiriXmlNode))
|
70
|
+
rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node");
|
71
|
+
|
72
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
73
|
+
Data_Get_Struct(rb_node, xmlNode, node);
|
74
|
+
|
75
|
+
if (xmlXPathNodeSetContains(node_set, node)) {
|
76
|
+
xmlXPathNodeSetDel(node_set, node);
|
77
|
+
return rb_node ;
|
78
|
+
}
|
79
|
+
|
80
|
+
return Qnil ;
|
81
|
+
}
|
82
|
+
|
83
|
+
|
84
|
+
/*
|
85
|
+
* call-seq:
|
86
|
+
* &(node_set)
|
87
|
+
*
|
88
|
+
* Set Intersection — Returns a new NodeSet containing nodes common to the two NodeSets.
|
89
|
+
*/
|
90
|
+
static VALUE intersection(VALUE self, VALUE rb_other)
|
91
|
+
{
|
92
|
+
xmlNodeSetPtr node_set;
|
93
|
+
xmlNodeSetPtr other;
|
94
|
+
|
95
|
+
if(! rb_funcall(rb_other, rb_intern("is_a?"), 1, cNokogiriXmlNodeSet))
|
96
|
+
rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");
|
97
|
+
|
98
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
99
|
+
Data_Get_Struct(rb_other, xmlNodeSet, other);
|
100
|
+
|
101
|
+
return Nokogiri_wrap_xml_node_set(xmlXPathIntersection(node_set, other));
|
102
|
+
}
|
103
|
+
|
104
|
+
|
105
|
+
/*
|
106
|
+
* call-seq:
|
107
|
+
* include?(node)
|
108
|
+
*
|
109
|
+
* Returns true if any member of node set equals +node+.
|
110
|
+
*/
|
111
|
+
static VALUE include_eh(VALUE self, VALUE rb_node)
|
112
|
+
{
|
113
|
+
xmlNodeSetPtr node_set;
|
114
|
+
xmlNodePtr node;
|
115
|
+
|
116
|
+
if(! rb_funcall(rb_node, rb_intern("is_a?"), 1, cNokogiriXmlNode))
|
117
|
+
rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node");
|
118
|
+
|
119
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
120
|
+
Data_Get_Struct(rb_node, xmlNode, node);
|
121
|
+
|
122
|
+
return (xmlXPathNodeSetContains(node_set, node) ? Qtrue : Qfalse);
|
123
|
+
}
|
124
|
+
|
125
|
+
|
126
|
+
/*
|
127
|
+
* call-seq:
|
128
|
+
* +(node_set)
|
129
|
+
*
|
130
|
+
* Concatenation - returns a new NodeSet built by concatenating the node set
|
131
|
+
* with +node_set+ to produce a third NodeSet
|
132
|
+
*/
|
133
|
+
static VALUE plus(VALUE self, VALUE rb_other)
|
134
|
+
{
|
135
|
+
xmlNodeSetPtr node_set;
|
136
|
+
xmlNodeSetPtr other;
|
137
|
+
xmlNodeSetPtr new;
|
138
|
+
|
139
|
+
if(! rb_funcall(rb_other, rb_intern("is_a?"), 1, cNokogiriXmlNodeSet))
|
140
|
+
rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");
|
141
|
+
|
142
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
143
|
+
Data_Get_Struct(rb_other, xmlNodeSet, other);
|
144
|
+
|
145
|
+
new = xmlXPathNodeSetMerge(NULL, node_set);
|
146
|
+
new = xmlXPathNodeSetMerge(new, other);
|
147
|
+
|
148
|
+
return Nokogiri_wrap_xml_node_set(new);
|
149
|
+
}
|
150
|
+
|
151
|
+
/*
|
152
|
+
* call-seq:
|
153
|
+
* -(node_set)
|
154
|
+
*
|
155
|
+
* Difference - returns a new NodeSet that is a copy of this NodeSet, removing
|
156
|
+
* each item that also appears in +node_set+
|
157
|
+
*/
|
158
|
+
static VALUE minus(VALUE self, VALUE rb_other)
|
159
|
+
{
|
160
|
+
xmlNodeSetPtr node_set;
|
161
|
+
xmlNodeSetPtr other;
|
162
|
+
xmlNodeSetPtr new;
|
163
|
+
int j ;
|
164
|
+
|
165
|
+
if(! rb_funcall(rb_other, rb_intern("is_a?"), 1, cNokogiriXmlNodeSet))
|
166
|
+
rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");
|
167
|
+
|
168
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
169
|
+
Data_Get_Struct(rb_other, xmlNodeSet, other);
|
170
|
+
|
171
|
+
new = xmlXPathNodeSetMerge(NULL, node_set);
|
172
|
+
for (j = 0 ; j < other->nodeNr ; ++j) {
|
173
|
+
xmlXPathNodeSetDel(new, other->nodeTab[j]);
|
174
|
+
}
|
175
|
+
|
176
|
+
return Nokogiri_wrap_xml_node_set(new);
|
177
|
+
}
|
178
|
+
|
179
|
+
|
180
|
+
static VALUE index_at(VALUE self, long offset)
|
181
|
+
{
|
182
|
+
xmlNodeSetPtr node_set;
|
183
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
184
|
+
|
185
|
+
if(offset >= node_set->nodeNr || abs(offset) > node_set->nodeNr) return Qnil;
|
186
|
+
if(offset < 0) offset = offset + node_set->nodeNr;
|
187
|
+
|
188
|
+
return Nokogiri_wrap_xml_node(Qnil, node_set->nodeTab[offset]);
|
189
|
+
}
|
190
|
+
|
191
|
+
static VALUE subseq(VALUE self, long beg, long len)
|
192
|
+
{
|
193
|
+
int j;
|
194
|
+
xmlNodeSetPtr node_set;
|
195
|
+
xmlNodeSetPtr new_set ;
|
196
|
+
|
197
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
198
|
+
|
199
|
+
if (beg > node_set->nodeNr) return Qnil ;
|
200
|
+
if (beg < 0 || len < 0) return Qnil ;
|
201
|
+
|
202
|
+
new_set = xmlXPathNodeSetCreate(NULL);
|
203
|
+
for (j = beg ; j < beg+len ; ++j) {
|
204
|
+
xmlXPathNodeSetAdd(new_set, node_set->nodeTab[j]);
|
205
|
+
}
|
206
|
+
return Nokogiri_wrap_xml_node_set(new_set);
|
207
|
+
}
|
208
|
+
|
209
|
+
/*
|
210
|
+
* call-seq:
|
211
|
+
* [index] -> Node or nil
|
212
|
+
* [start, length] -> NodeSet or nil
|
213
|
+
* [range] -> NodeSet or nil
|
214
|
+
* slice(index) -> Node or nil
|
215
|
+
* slice(start, length) -> NodeSet or nil
|
216
|
+
* slice(range) -> NodeSet or nil
|
217
|
+
*
|
218
|
+
* Element reference - returns the node at +index+, or returns a NodeSet
|
219
|
+
* containing nodes starting at +start+ and continuing for +length+ elements, or
|
220
|
+
* returns a NodeSet containing nodes specified by +range+. Negative +indices+
|
221
|
+
* count backward from the end of the +node_set+ (-1 is the last node). Returns
|
222
|
+
* nil if the +index+ (or +start+) are out of range.
|
223
|
+
*/
|
224
|
+
static VALUE slice(int argc, VALUE *argv, VALUE self)
|
225
|
+
{
|
226
|
+
VALUE arg ;
|
227
|
+
long beg, len ;
|
228
|
+
xmlNodeSetPtr node_set;
|
229
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
230
|
+
|
231
|
+
if (argc == 2) {
|
232
|
+
beg = NUM2LONG(argv[0]);
|
233
|
+
len = NUM2LONG(argv[1]);
|
234
|
+
if (beg < 0) {
|
235
|
+
beg += node_set->nodeNr ;
|
236
|
+
}
|
237
|
+
return subseq(self, beg, len);
|
238
|
+
}
|
239
|
+
|
240
|
+
if (argc != 1) {
|
241
|
+
rb_scan_args(argc, argv, "11", NULL, NULL);
|
242
|
+
}
|
243
|
+
arg = argv[0];
|
244
|
+
|
245
|
+
if (FIXNUM_P(arg)) {
|
246
|
+
return index_at(self, FIX2LONG(arg));
|
247
|
+
}
|
248
|
+
|
249
|
+
/* if arg is Range */
|
250
|
+
switch (rb_range_beg_len(arg, &beg, &len, node_set->nodeNr, 0)) {
|
251
|
+
case Qfalse:
|
252
|
+
break;
|
253
|
+
case Qnil:
|
254
|
+
return Qnil;
|
255
|
+
default:
|
256
|
+
return subseq(self, beg, len);
|
257
|
+
}
|
258
|
+
|
259
|
+
return index_at(self, NUM2LONG(arg));
|
260
|
+
}
|
261
|
+
|
262
|
+
|
263
|
+
/*
|
264
|
+
* call-seq:
|
265
|
+
* to_a
|
266
|
+
*
|
267
|
+
* Return this list as an Array
|
268
|
+
*/
|
269
|
+
static VALUE to_array(VALUE self, VALUE rb_node)
|
270
|
+
{
|
271
|
+
xmlNodeSetPtr set;
|
272
|
+
Data_Get_Struct(self, xmlNodeSet, set);
|
273
|
+
|
274
|
+
VALUE *elts = calloc((size_t)set->nodeNr, sizeof(VALUE *));
|
275
|
+
int i;
|
276
|
+
for(i = 0; i < set->nodeNr; i++) {
|
277
|
+
if(set->nodeTab[i]->_private) {
|
278
|
+
elts[i] = (VALUE)set->nodeTab[i]->_private;
|
279
|
+
} else {
|
280
|
+
elts[i] = Nokogiri_wrap_xml_node(Qnil, set->nodeTab[i]);
|
281
|
+
}
|
282
|
+
}
|
283
|
+
|
284
|
+
VALUE list = rb_ary_new4(set->nodeNr, elts);
|
285
|
+
|
286
|
+
free(elts);
|
287
|
+
|
288
|
+
return list;
|
289
|
+
}
|
290
|
+
|
291
|
+
/*
|
292
|
+
* call-seq:
|
293
|
+
* unlink
|
294
|
+
*
|
295
|
+
* Unlink this NodeSet and all Node objects it contains from their current context.
|
296
|
+
*/
|
297
|
+
static VALUE unlink_nodeset(VALUE self)
|
298
|
+
{
|
299
|
+
xmlNodeSetPtr node_set;
|
300
|
+
int j, nodeNr ;
|
301
|
+
|
302
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
303
|
+
nodeNr = node_set->nodeNr ;
|
304
|
+
for (j = 0 ; j < nodeNr ; j++) {
|
305
|
+
VALUE node ;
|
306
|
+
xmlNodePtr node_ptr;
|
307
|
+
node = Nokogiri_wrap_xml_node(Qnil, node_set->nodeTab[j]);
|
308
|
+
rb_funcall(node, rb_intern("unlink"), 0); /* modifies the C struct out from under the object */
|
309
|
+
Data_Get_Struct(node, xmlNode, node_ptr);
|
310
|
+
node_set->nodeTab[j] = node_ptr ;
|
311
|
+
}
|
312
|
+
return self ;
|
313
|
+
}
|
314
|
+
|
315
|
+
|
316
|
+
static void deallocate(xmlNodeSetPtr node_set)
|
317
|
+
{
|
318
|
+
/*
|
319
|
+
* xmlXPathFreeNodeSet() contains an implicit assumption that it is being
|
320
|
+
* called before any of its pointed-to nodes have been free()d. this
|
321
|
+
* assumption lies in the operation where it dereferences nodeTab pointers
|
322
|
+
* while searching for namespace nodes to free.
|
323
|
+
*
|
324
|
+
* however, since Ruby's GC mechanism cannot guarantee the strict order in
|
325
|
+
* which ruby objects will be GC'd, nodes may be garbage collected before a
|
326
|
+
* nodeset containing pointers to those nodes. (this is true regardless of
|
327
|
+
* how we declare dependencies between objects with rb_gc_mark().)
|
328
|
+
*
|
329
|
+
* as a result, xmlXPathFreeNodeSet() will perform unsafe memory operations,
|
330
|
+
* and calling it would be evil.
|
331
|
+
*
|
332
|
+
* on the bright side, though, Nokogiri's API currently does not cause
|
333
|
+
* namespace nodes to be included in node sets, ever.
|
334
|
+
*
|
335
|
+
* armed with that fact, we examined xmlXPathFreeNodeSet() and related libxml
|
336
|
+
* code and determined that, within the Nokogiri abstraction, we will not
|
337
|
+
* leak memory if we simply free the node set's memory directly. that's only
|
338
|
+
* quasi-evil!
|
339
|
+
*
|
340
|
+
* there's probably a lesson in here somewhere about intermingling, within a
|
341
|
+
* single array, structs with different memory-ownership semantics. or more
|
342
|
+
* generally, a lesson about building an API in C/C++ that does not contain
|
343
|
+
* assumptions about the strict order in which memory will be released. hey,
|
344
|
+
* that sounds like a great idea for a blog post! get to it!
|
345
|
+
*
|
346
|
+
* "In Valgrind We Trust." seriously.
|
347
|
+
*/
|
348
|
+
NOKOGIRI_DEBUG_START(node_set) ;
|
349
|
+
if (node_set->nodeTab != NULL)
|
350
|
+
xmlFree(node_set->nodeTab);
|
351
|
+
xmlFree(node_set);
|
352
|
+
NOKOGIRI_DEBUG_END(node_set) ;
|
353
|
+
}
|
354
|
+
|
355
|
+
static VALUE allocate(VALUE klass)
|
356
|
+
{
|
357
|
+
return Nokogiri_wrap_xml_node_set(xmlXPathNodeSetCreate(NULL));
|
358
|
+
}
|
359
|
+
|
360
|
+
VALUE Nokogiri_wrap_xml_node_set(xmlNodeSetPtr node_set)
|
361
|
+
{
|
362
|
+
return Data_Wrap_Struct(cNokogiriXmlNodeSet, 0, deallocate, node_set);
|
363
|
+
}
|
364
|
+
|
365
|
+
VALUE cNokogiriXmlNodeSet ;
|
366
|
+
void init_xml_node_set(void)
|
367
|
+
{
|
368
|
+
VALUE nokogiri = rb_define_module("Nokogiri");
|
369
|
+
VALUE xml = rb_define_module_under(nokogiri, "XML");
|
370
|
+
VALUE klass = rb_define_class_under(xml, "NodeSet", rb_cObject);
|
371
|
+
cNokogiriXmlNodeSet = klass;
|
372
|
+
|
373
|
+
rb_define_alloc_func(klass, allocate);
|
374
|
+
rb_define_method(klass, "length", length, 0);
|
375
|
+
rb_define_method(klass, "[]", slice, -1);
|
376
|
+
rb_define_method(klass, "slice", slice, -1);
|
377
|
+
rb_define_method(klass, "push", push, 1);
|
378
|
+
rb_define_method(klass, "+", plus, 1);
|
379
|
+
rb_define_method(klass, "-", minus, 1);
|
380
|
+
rb_define_method(klass, "unlink", unlink_nodeset, 0);
|
381
|
+
rb_define_method(klass, "to_a", to_array, 0);
|
382
|
+
rb_define_method(klass, "dup", duplicate, 0);
|
383
|
+
rb_define_method(klass, "delete", delete, 1);
|
384
|
+
rb_define_method(klass, "&", intersection, 1);
|
385
|
+
rb_define_method(klass, "include?", include_eh, 1);
|
386
|
+
}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#include <xml_processing_instruction.h>
|
2
|
+
|
3
|
+
/*
|
4
|
+
* call-seq:
|
5
|
+
* new(document, name, content)
|
6
|
+
*
|
7
|
+
* Create a new ProcessingInstruction element on the +document+ with +name+
|
8
|
+
* and +content+
|
9
|
+
*/
|
10
|
+
static VALUE new(int argc, VALUE *argv, VALUE klass)
|
11
|
+
{
|
12
|
+
xmlDocPtr xml_doc;
|
13
|
+
VALUE document;
|
14
|
+
VALUE name;
|
15
|
+
VALUE content;
|
16
|
+
VALUE rest;
|
17
|
+
|
18
|
+
rb_scan_args(argc, argv, "3*", &document, &name, &content, &rest);
|
19
|
+
|
20
|
+
Data_Get_Struct(document, xmlDoc, xml_doc);
|
21
|
+
|
22
|
+
xmlNodePtr node = xmlNewDocPI(
|
23
|
+
xml_doc,
|
24
|
+
(const xmlChar *)StringValuePtr(name),
|
25
|
+
(const xmlChar *)StringValuePtr(content)
|
26
|
+
);
|
27
|
+
|
28
|
+
NOKOGIRI_ROOT_NODE(node);
|
29
|
+
|
30
|
+
VALUE rb_node = Nokogiri_wrap_xml_node(klass, node);
|
31
|
+
rb_funcall2(rb_node, rb_intern("initialize"), argc, argv);
|
32
|
+
|
33
|
+
if(rb_block_given_p()) rb_yield(rb_node);
|
34
|
+
|
35
|
+
return rb_node;
|
36
|
+
}
|
37
|
+
|
38
|
+
VALUE cNokogiriXmlProcessingInstruction;
|
39
|
+
void init_xml_processing_instruction()
|
40
|
+
{
|
41
|
+
VALUE nokogiri = rb_define_module("Nokogiri");
|
42
|
+
VALUE xml = rb_define_module_under(nokogiri, "XML");
|
43
|
+
VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
|
44
|
+
|
45
|
+
/*
|
46
|
+
* ProcessingInstruction represents a ProcessingInstruction node in an xml
|
47
|
+
* document.
|
48
|
+
*/
|
49
|
+
VALUE klass = rb_define_class_under(xml, "ProcessingInstruction", node);
|
50
|
+
|
51
|
+
cNokogiriXmlProcessingInstruction = klass;
|
52
|
+
|
53
|
+
rb_define_singleton_method(klass, "new", new, -1);
|
54
|
+
}
|