nokogiri 1.11.0.rc4-arm64-darwin
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of nokogiri might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/LICENSE-DEPENDENCIES.md +1682 -0
- data/LICENSE.md +9 -0
- data/README.md +200 -0
- data/bin/nokogiri +118 -0
- data/dependencies.yml +74 -0
- data/ext/nokogiri/depend +477 -0
- data/ext/nokogiri/extconf.rb +819 -0
- data/ext/nokogiri/html_document.c +171 -0
- data/ext/nokogiri/html_document.h +10 -0
- data/ext/nokogiri/html_element_description.c +279 -0
- data/ext/nokogiri/html_element_description.h +10 -0
- data/ext/nokogiri/html_entity_lookup.c +32 -0
- data/ext/nokogiri/html_entity_lookup.h +8 -0
- data/ext/nokogiri/html_sax_parser_context.c +116 -0
- data/ext/nokogiri/html_sax_parser_context.h +11 -0
- data/ext/nokogiri/html_sax_push_parser.c +87 -0
- data/ext/nokogiri/html_sax_push_parser.h +9 -0
- data/ext/nokogiri/include/libexslt/exslt.h +102 -0
- data/ext/nokogiri/include/libexslt/exsltconfig.h +70 -0
- data/ext/nokogiri/include/libexslt/exsltexports.h +140 -0
- data/ext/nokogiri/include/libxml2/libxml/DOCBparser.h +96 -0
- data/ext/nokogiri/include/libxml2/libxml/HTMLparser.h +306 -0
- data/ext/nokogiri/include/libxml2/libxml/HTMLtree.h +147 -0
- data/ext/nokogiri/include/libxml2/libxml/SAX.h +173 -0
- data/ext/nokogiri/include/libxml2/libxml/SAX2.h +178 -0
- data/ext/nokogiri/include/libxml2/libxml/c14n.h +126 -0
- data/ext/nokogiri/include/libxml2/libxml/catalog.h +182 -0
- data/ext/nokogiri/include/libxml2/libxml/chvalid.h +230 -0
- data/ext/nokogiri/include/libxml2/libxml/debugXML.h +217 -0
- data/ext/nokogiri/include/libxml2/libxml/dict.h +79 -0
- data/ext/nokogiri/include/libxml2/libxml/encoding.h +245 -0
- data/ext/nokogiri/include/libxml2/libxml/entities.h +151 -0
- data/ext/nokogiri/include/libxml2/libxml/globals.h +508 -0
- data/ext/nokogiri/include/libxml2/libxml/hash.h +236 -0
- data/ext/nokogiri/include/libxml2/libxml/list.h +137 -0
- data/ext/nokogiri/include/libxml2/libxml/nanoftp.h +163 -0
- data/ext/nokogiri/include/libxml2/libxml/nanohttp.h +81 -0
- data/ext/nokogiri/include/libxml2/libxml/parser.h +1241 -0
- data/ext/nokogiri/include/libxml2/libxml/parserInternals.h +644 -0
- data/ext/nokogiri/include/libxml2/libxml/pattern.h +100 -0
- data/ext/nokogiri/include/libxml2/libxml/relaxng.h +217 -0
- data/ext/nokogiri/include/libxml2/libxml/schemasInternals.h +958 -0
- data/ext/nokogiri/include/libxml2/libxml/schematron.h +142 -0
- data/ext/nokogiri/include/libxml2/libxml/threads.h +89 -0
- data/ext/nokogiri/include/libxml2/libxml/tree.h +1311 -0
- data/ext/nokogiri/include/libxml2/libxml/uri.h +94 -0
- data/ext/nokogiri/include/libxml2/libxml/valid.h +458 -0
- data/ext/nokogiri/include/libxml2/libxml/xinclude.h +129 -0
- data/ext/nokogiri/include/libxml2/libxml/xlink.h +189 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlIO.h +366 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlautomata.h +146 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlerror.h +945 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlexports.h +153 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlmemory.h +224 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlmodule.h +57 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlreader.h +428 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlregexp.h +222 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlsave.h +88 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlschemas.h +246 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlschemastypes.h +151 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlstring.h +140 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlunicode.h +202 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlversion.h +485 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlwriter.h +488 -0
- data/ext/nokogiri/include/libxml2/libxml/xpath.h +566 -0
- data/ext/nokogiri/include/libxml2/libxml/xpathInternals.h +632 -0
- data/ext/nokogiri/include/libxml2/libxml/xpointer.h +114 -0
- data/ext/nokogiri/include/libxslt/attributes.h +38 -0
- data/ext/nokogiri/include/libxslt/documents.h +93 -0
- data/ext/nokogiri/include/libxslt/extensions.h +262 -0
- data/ext/nokogiri/include/libxslt/extra.h +72 -0
- data/ext/nokogiri/include/libxslt/functions.h +78 -0
- data/ext/nokogiri/include/libxslt/imports.h +75 -0
- data/ext/nokogiri/include/libxslt/keys.h +53 -0
- data/ext/nokogiri/include/libxslt/namespaces.h +68 -0
- data/ext/nokogiri/include/libxslt/numbersInternals.h +73 -0
- data/ext/nokogiri/include/libxslt/pattern.h +84 -0
- data/ext/nokogiri/include/libxslt/preproc.h +43 -0
- data/ext/nokogiri/include/libxslt/security.h +104 -0
- data/ext/nokogiri/include/libxslt/templates.h +77 -0
- data/ext/nokogiri/include/libxslt/transform.h +207 -0
- data/ext/nokogiri/include/libxslt/variables.h +118 -0
- data/ext/nokogiri/include/libxslt/xslt.h +110 -0
- data/ext/nokogiri/include/libxslt/xsltInternals.h +1978 -0
- data/ext/nokogiri/include/libxslt/xsltconfig.h +180 -0
- data/ext/nokogiri/include/libxslt/xsltexports.h +142 -0
- data/ext/nokogiri/include/libxslt/xsltlocale.h +76 -0
- data/ext/nokogiri/include/libxslt/xsltutils.h +313 -0
- data/ext/nokogiri/nokogiri.c +135 -0
- data/ext/nokogiri/nokogiri.h +130 -0
- data/ext/nokogiri/xml_attr.c +103 -0
- data/ext/nokogiri/xml_attr.h +9 -0
- data/ext/nokogiri/xml_attribute_decl.c +70 -0
- data/ext/nokogiri/xml_attribute_decl.h +9 -0
- data/ext/nokogiri/xml_cdata.c +62 -0
- data/ext/nokogiri/xml_cdata.h +9 -0
- data/ext/nokogiri/xml_comment.c +69 -0
- data/ext/nokogiri/xml_comment.h +9 -0
- data/ext/nokogiri/xml_document.c +622 -0
- data/ext/nokogiri/xml_document.h +23 -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 +202 -0
- data/ext/nokogiri/xml_dtd.h +10 -0
- data/ext/nokogiri/xml_element_content.c +123 -0
- data/ext/nokogiri/xml_element_content.h +10 -0
- data/ext/nokogiri/xml_element_decl.c +69 -0
- data/ext/nokogiri/xml_element_decl.h +9 -0
- data/ext/nokogiri/xml_encoding_handler.c +79 -0
- data/ext/nokogiri/xml_encoding_handler.h +8 -0
- data/ext/nokogiri/xml_entity_decl.c +110 -0
- data/ext/nokogiri/xml_entity_decl.h +10 -0
- data/ext/nokogiri/xml_entity_reference.c +52 -0
- data/ext/nokogiri/xml_entity_reference.h +9 -0
- data/ext/nokogiri/xml_io.c +63 -0
- data/ext/nokogiri/xml_io.h +11 -0
- data/ext/nokogiri/xml_libxml2_hacks.c +112 -0
- data/ext/nokogiri/xml_libxml2_hacks.h +12 -0
- data/ext/nokogiri/xml_namespace.c +111 -0
- data/ext/nokogiri/xml_namespace.h +14 -0
- data/ext/nokogiri/xml_node.c +1773 -0
- data/ext/nokogiri/xml_node.h +13 -0
- data/ext/nokogiri/xml_node_set.c +486 -0
- data/ext/nokogiri/xml_node_set.h +12 -0
- data/ext/nokogiri/xml_processing_instruction.c +56 -0
- data/ext/nokogiri/xml_processing_instruction.h +9 -0
- data/ext/nokogiri/xml_reader.c +657 -0
- data/ext/nokogiri/xml_reader.h +10 -0
- data/ext/nokogiri/xml_relax_ng.c +179 -0
- data/ext/nokogiri/xml_relax_ng.h +9 -0
- data/ext/nokogiri/xml_sax_parser.c +305 -0
- data/ext/nokogiri/xml_sax_parser.h +39 -0
- data/ext/nokogiri/xml_sax_parser_context.c +262 -0
- data/ext/nokogiri/xml_sax_parser_context.h +10 -0
- data/ext/nokogiri/xml_sax_push_parser.c +159 -0
- data/ext/nokogiri/xml_sax_push_parser.h +9 -0
- data/ext/nokogiri/xml_schema.c +276 -0
- data/ext/nokogiri/xml_schema.h +9 -0
- data/ext/nokogiri/xml_syntax_error.c +64 -0
- data/ext/nokogiri/xml_syntax_error.h +13 -0
- data/ext/nokogiri/xml_text.c +52 -0
- data/ext/nokogiri/xml_text.h +9 -0
- data/ext/nokogiri/xml_xpath_context.c +374 -0
- data/ext/nokogiri/xml_xpath_context.h +10 -0
- data/ext/nokogiri/xslt_stylesheet.c +263 -0
- data/ext/nokogiri/xslt_stylesheet.h +14 -0
- data/lib/nokogiri.rb +127 -0
- data/lib/nokogiri/2.5/nokogiri.bundle +0 -0
- data/lib/nokogiri/2.6/nokogiri.bundle +0 -0
- data/lib/nokogiri/2.7/nokogiri.bundle +0 -0
- data/lib/nokogiri/3.0/nokogiri.bundle +0 -0
- data/lib/nokogiri/css.rb +28 -0
- data/lib/nokogiri/css/node.rb +53 -0
- data/lib/nokogiri/css/parser.rb +751 -0
- data/lib/nokogiri/css/parser.y +272 -0
- data/lib/nokogiri/css/parser_extras.rb +94 -0
- data/lib/nokogiri/css/syntax_error.rb +8 -0
- data/lib/nokogiri/css/tokenizer.rb +154 -0
- data/lib/nokogiri/css/tokenizer.rex +55 -0
- data/lib/nokogiri/css/xpath_visitor.rb +260 -0
- data/lib/nokogiri/decorators/slop.rb +43 -0
- data/lib/nokogiri/html.rb +38 -0
- data/lib/nokogiri/html/builder.rb +36 -0
- data/lib/nokogiri/html/document.rb +322 -0
- data/lib/nokogiri/html/document_fragment.rb +50 -0
- data/lib/nokogiri/html/element_description.rb +24 -0
- data/lib/nokogiri/html/element_description_defaults.rb +672 -0
- data/lib/nokogiri/html/entity_lookup.rb +14 -0
- data/lib/nokogiri/html/sax/parser.rb +63 -0
- data/lib/nokogiri/html/sax/parser_context.rb +17 -0
- data/lib/nokogiri/html/sax/push_parser.rb +37 -0
- data/lib/nokogiri/jruby/dependencies.rb +20 -0
- data/lib/nokogiri/syntax_error.rb +5 -0
- data/lib/nokogiri/version.rb +3 -0
- data/lib/nokogiri/version/constant.rb +5 -0
- data/lib/nokogiri/version/info.rb +182 -0
- data/lib/nokogiri/xml.rb +76 -0
- data/lib/nokogiri/xml/attr.rb +15 -0
- data/lib/nokogiri/xml/attribute_decl.rb +19 -0
- data/lib/nokogiri/xml/builder.rb +447 -0
- data/lib/nokogiri/xml/cdata.rb +12 -0
- data/lib/nokogiri/xml/character_data.rb +8 -0
- data/lib/nokogiri/xml/document.rb +290 -0
- data/lib/nokogiri/xml/document_fragment.rb +159 -0
- data/lib/nokogiri/xml/dtd.rb +33 -0
- data/lib/nokogiri/xml/element_content.rb +37 -0
- data/lib/nokogiri/xml/element_decl.rb +14 -0
- data/lib/nokogiri/xml/entity_decl.rb +20 -0
- data/lib/nokogiri/xml/entity_reference.rb +19 -0
- data/lib/nokogiri/xml/namespace.rb +14 -0
- data/lib/nokogiri/xml/node.rb +1240 -0
- data/lib/nokogiri/xml/node/save_options.rb +62 -0
- data/lib/nokogiri/xml/node_set.rb +372 -0
- data/lib/nokogiri/xml/notation.rb +7 -0
- data/lib/nokogiri/xml/parse_options.rb +127 -0
- data/lib/nokogiri/xml/pp.rb +3 -0
- data/lib/nokogiri/xml/pp/character_data.rb +19 -0
- data/lib/nokogiri/xml/pp/node.rb +57 -0
- data/lib/nokogiri/xml/processing_instruction.rb +9 -0
- data/lib/nokogiri/xml/reader.rb +116 -0
- data/lib/nokogiri/xml/relax_ng.rb +37 -0
- data/lib/nokogiri/xml/sax.rb +5 -0
- data/lib/nokogiri/xml/sax/document.rb +172 -0
- data/lib/nokogiri/xml/sax/parser.rb +123 -0
- data/lib/nokogiri/xml/sax/parser_context.rb +17 -0
- data/lib/nokogiri/xml/sax/push_parser.rb +61 -0
- data/lib/nokogiri/xml/schema.rb +72 -0
- data/lib/nokogiri/xml/searchable.rb +239 -0
- data/lib/nokogiri/xml/syntax_error.rb +71 -0
- data/lib/nokogiri/xml/text.rb +10 -0
- data/lib/nokogiri/xml/xpath.rb +11 -0
- data/lib/nokogiri/xml/xpath/syntax_error.rb +12 -0
- data/lib/nokogiri/xml/xpath_context.rb +17 -0
- data/lib/nokogiri/xslt.rb +57 -0
- data/lib/nokogiri/xslt/stylesheet.rb +26 -0
- data/lib/xsd/xmlparser/nokogiri.rb +103 -0
- metadata +565 -0
@@ -0,0 +1,13 @@
|
|
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
|
+
|
11
|
+
VALUE Nokogiri_wrap_xml_node(VALUE klass, xmlNodePtr node) ;
|
12
|
+
void Nokogiri_xml_node_properties(xmlNodePtr node, VALUE attr_hash) ;
|
13
|
+
#endif
|
@@ -0,0 +1,486 @@
|
|
1
|
+
#include <xml_node_set.h>
|
2
|
+
#include <xml_namespace.h>
|
3
|
+
#include <libxml/xpathInternals.h>
|
4
|
+
|
5
|
+
static ID decorate ;
|
6
|
+
static void xpath_node_set_del(xmlNodeSetPtr cur, xmlNodePtr val);
|
7
|
+
|
8
|
+
|
9
|
+
static void Check_Node_Set_Node_Type(VALUE node)
|
10
|
+
{
|
11
|
+
if (!(rb_obj_is_kind_of(node, cNokogiriXmlNode) ||
|
12
|
+
rb_obj_is_kind_of(node, cNokogiriXmlNamespace))) {
|
13
|
+
rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node or Nokogiri::XML::Namespace");
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
|
18
|
+
static void deallocate(xmlNodeSetPtr node_set)
|
19
|
+
{
|
20
|
+
/*
|
21
|
+
*
|
22
|
+
* since xpath queries return copies of the xmlNs structs,
|
23
|
+
* xmlXPathFreeNodeSet() frees those xmlNs structs that are in the
|
24
|
+
* NodeSet.
|
25
|
+
*
|
26
|
+
* this is bad if someone is still trying to use the Namespace object wrapped
|
27
|
+
* around the xmlNs, so we need to avoid that.
|
28
|
+
*
|
29
|
+
* here we reproduce xmlXPathFreeNodeSet() without the xmlNs logic.
|
30
|
+
*
|
31
|
+
* this doesn't cause a leak because Namespace objects that are in an XPath
|
32
|
+
* query NodeSet are given their own lifecycle in
|
33
|
+
* Nokogiri_wrap_xml_namespace().
|
34
|
+
*/
|
35
|
+
NOKOGIRI_DEBUG_START(node_set) ;
|
36
|
+
if (node_set->nodeTab != NULL)
|
37
|
+
xmlFree(node_set->nodeTab);
|
38
|
+
|
39
|
+
xmlFree(node_set);
|
40
|
+
NOKOGIRI_DEBUG_END(node_set) ;
|
41
|
+
}
|
42
|
+
|
43
|
+
static VALUE allocate(VALUE klass)
|
44
|
+
{
|
45
|
+
return Nokogiri_wrap_xml_node_set(xmlXPathNodeSetCreate(NULL), Qnil);
|
46
|
+
}
|
47
|
+
|
48
|
+
|
49
|
+
/*
|
50
|
+
* call-seq:
|
51
|
+
* dup
|
52
|
+
*
|
53
|
+
* Duplicate this NodeSet. Note that the Nodes contained in the NodeSet are not
|
54
|
+
* duplicated (similar to how Array and other Enumerable classes work).
|
55
|
+
*/
|
56
|
+
static VALUE duplicate(VALUE self)
|
57
|
+
{
|
58
|
+
xmlNodeSetPtr node_set;
|
59
|
+
xmlNodeSetPtr dupl;
|
60
|
+
|
61
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
62
|
+
|
63
|
+
dupl = xmlXPathNodeSetMerge(NULL, node_set);
|
64
|
+
|
65
|
+
return Nokogiri_wrap_xml_node_set(dupl, rb_iv_get(self, "@document"));
|
66
|
+
}
|
67
|
+
|
68
|
+
/*
|
69
|
+
* call-seq:
|
70
|
+
* length
|
71
|
+
*
|
72
|
+
* Get the length of the node set
|
73
|
+
*/
|
74
|
+
static VALUE length(VALUE self)
|
75
|
+
{
|
76
|
+
xmlNodeSetPtr node_set;
|
77
|
+
|
78
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
79
|
+
|
80
|
+
return node_set ? INT2NUM(node_set->nodeNr) : INT2NUM(0);
|
81
|
+
}
|
82
|
+
|
83
|
+
/*
|
84
|
+
* call-seq:
|
85
|
+
* push(node)
|
86
|
+
*
|
87
|
+
* Append +node+ to the NodeSet.
|
88
|
+
*/
|
89
|
+
static VALUE push(VALUE self, VALUE rb_node)
|
90
|
+
{
|
91
|
+
xmlNodeSetPtr node_set;
|
92
|
+
xmlNodePtr node;
|
93
|
+
|
94
|
+
Check_Node_Set_Node_Type(rb_node);
|
95
|
+
|
96
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
97
|
+
Data_Get_Struct(rb_node, xmlNode, node);
|
98
|
+
|
99
|
+
xmlXPathNodeSetAdd(node_set, node);
|
100
|
+
|
101
|
+
return self;
|
102
|
+
}
|
103
|
+
|
104
|
+
/*
|
105
|
+
* call-seq:
|
106
|
+
* delete(node)
|
107
|
+
*
|
108
|
+
* Delete +node+ from the Nodeset, if it is a member. Returns the deleted node
|
109
|
+
* if found, otherwise returns nil.
|
110
|
+
*/
|
111
|
+
static VALUE
|
112
|
+
delete(VALUE self, VALUE rb_node)
|
113
|
+
{
|
114
|
+
xmlNodeSetPtr node_set;
|
115
|
+
xmlNodePtr node;
|
116
|
+
|
117
|
+
Check_Node_Set_Node_Type(rb_node);
|
118
|
+
|
119
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
120
|
+
Data_Get_Struct(rb_node, xmlNode, node);
|
121
|
+
|
122
|
+
if (xmlXPathNodeSetContains(node_set, node)) {
|
123
|
+
xpath_node_set_del(node_set, node);
|
124
|
+
return rb_node;
|
125
|
+
}
|
126
|
+
return Qnil ;
|
127
|
+
}
|
128
|
+
|
129
|
+
|
130
|
+
/*
|
131
|
+
* call-seq:
|
132
|
+
* &(node_set)
|
133
|
+
*
|
134
|
+
* Set Intersection — Returns a new NodeSet containing nodes common to the two NodeSets.
|
135
|
+
*/
|
136
|
+
static VALUE intersection(VALUE self, VALUE rb_other)
|
137
|
+
{
|
138
|
+
xmlNodeSetPtr node_set, other ;
|
139
|
+
xmlNodeSetPtr intersection;
|
140
|
+
|
141
|
+
if(!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet))
|
142
|
+
rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");
|
143
|
+
|
144
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
145
|
+
Data_Get_Struct(rb_other, xmlNodeSet, other);
|
146
|
+
|
147
|
+
intersection = xmlXPathIntersection(node_set, other);
|
148
|
+
return Nokogiri_wrap_xml_node_set(intersection, rb_iv_get(self, "@document"));
|
149
|
+
}
|
150
|
+
|
151
|
+
|
152
|
+
/*
|
153
|
+
* call-seq:
|
154
|
+
* include?(node)
|
155
|
+
*
|
156
|
+
* Returns true if any member of node set equals +node+.
|
157
|
+
*/
|
158
|
+
static VALUE include_eh(VALUE self, VALUE rb_node)
|
159
|
+
{
|
160
|
+
xmlNodeSetPtr node_set;
|
161
|
+
xmlNodePtr node;
|
162
|
+
|
163
|
+
Check_Node_Set_Node_Type(rb_node);
|
164
|
+
|
165
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
166
|
+
Data_Get_Struct(rb_node, xmlNode, node);
|
167
|
+
|
168
|
+
return (xmlXPathNodeSetContains(node_set, node) ? Qtrue : Qfalse);
|
169
|
+
}
|
170
|
+
|
171
|
+
|
172
|
+
/*
|
173
|
+
* call-seq:
|
174
|
+
* |(node_set)
|
175
|
+
*
|
176
|
+
* Returns a new set built by merging the set and the elements of the given
|
177
|
+
* set.
|
178
|
+
*/
|
179
|
+
static VALUE set_union(VALUE self, VALUE rb_other)
|
180
|
+
{
|
181
|
+
xmlNodeSetPtr node_set, other;
|
182
|
+
xmlNodeSetPtr new;
|
183
|
+
|
184
|
+
if(!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet))
|
185
|
+
rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");
|
186
|
+
|
187
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
188
|
+
Data_Get_Struct(rb_other, xmlNodeSet, other);
|
189
|
+
|
190
|
+
new = xmlXPathNodeSetMerge(NULL, node_set);
|
191
|
+
new = xmlXPathNodeSetMerge(new, other);
|
192
|
+
|
193
|
+
return Nokogiri_wrap_xml_node_set(new, rb_iv_get(self, "@document"));
|
194
|
+
}
|
195
|
+
|
196
|
+
/*
|
197
|
+
* call-seq:
|
198
|
+
* -(node_set)
|
199
|
+
*
|
200
|
+
* Difference - returns a new NodeSet that is a copy of this NodeSet, removing
|
201
|
+
* each item that also appears in +node_set+
|
202
|
+
*/
|
203
|
+
static VALUE minus(VALUE self, VALUE rb_other)
|
204
|
+
{
|
205
|
+
xmlNodeSetPtr node_set, other;
|
206
|
+
xmlNodeSetPtr new;
|
207
|
+
int j ;
|
208
|
+
|
209
|
+
if(!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet))
|
210
|
+
rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");
|
211
|
+
|
212
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
213
|
+
Data_Get_Struct(rb_other, xmlNodeSet, other);
|
214
|
+
|
215
|
+
new = xmlXPathNodeSetMerge(NULL, node_set);
|
216
|
+
for (j = 0 ; j < other->nodeNr ; ++j) {
|
217
|
+
xpath_node_set_del(new, other->nodeTab[j]);
|
218
|
+
}
|
219
|
+
|
220
|
+
return Nokogiri_wrap_xml_node_set(new, rb_iv_get(self, "@document"));
|
221
|
+
}
|
222
|
+
|
223
|
+
|
224
|
+
static VALUE index_at(VALUE self, long offset)
|
225
|
+
{
|
226
|
+
xmlNodeSetPtr node_set;
|
227
|
+
|
228
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
229
|
+
|
230
|
+
if (offset >= node_set->nodeNr || abs((int)offset) > node_set->nodeNr) {
|
231
|
+
return Qnil;
|
232
|
+
}
|
233
|
+
|
234
|
+
if (offset < 0) { offset += node_set->nodeNr ; }
|
235
|
+
|
236
|
+
return Nokogiri_wrap_xml_node_set_node(node_set->nodeTab[offset], self);
|
237
|
+
}
|
238
|
+
|
239
|
+
static VALUE subseq(VALUE self, long beg, long len)
|
240
|
+
{
|
241
|
+
long j;
|
242
|
+
xmlNodeSetPtr node_set;
|
243
|
+
xmlNodeSetPtr new_set ;
|
244
|
+
|
245
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
246
|
+
|
247
|
+
if (beg > node_set->nodeNr) return Qnil ;
|
248
|
+
if (beg < 0 || len < 0) return Qnil ;
|
249
|
+
|
250
|
+
if ((beg + len) > node_set->nodeNr) {
|
251
|
+
len = node_set->nodeNr - beg ;
|
252
|
+
}
|
253
|
+
|
254
|
+
new_set = xmlXPathNodeSetCreate(NULL);
|
255
|
+
for (j = beg ; j < beg+len ; ++j) {
|
256
|
+
xmlXPathNodeSetAddUnique(new_set, node_set->nodeTab[j]);
|
257
|
+
}
|
258
|
+
return Nokogiri_wrap_xml_node_set(new_set, rb_iv_get(self, "@document"));
|
259
|
+
}
|
260
|
+
|
261
|
+
/*
|
262
|
+
* call-seq:
|
263
|
+
* [index] -> Node or nil
|
264
|
+
* [start, length] -> NodeSet or nil
|
265
|
+
* [range] -> NodeSet or nil
|
266
|
+
* slice(index) -> Node or nil
|
267
|
+
* slice(start, length) -> NodeSet or nil
|
268
|
+
* slice(range) -> NodeSet or nil
|
269
|
+
*
|
270
|
+
* Element reference - returns the node at +index+, or returns a NodeSet
|
271
|
+
* containing nodes starting at +start+ and continuing for +length+ elements, or
|
272
|
+
* returns a NodeSet containing nodes specified by +range+. Negative +indices+
|
273
|
+
* count backward from the end of the +node_set+ (-1 is the last node). Returns
|
274
|
+
* nil if the +index+ (or +start+) are out of range.
|
275
|
+
*/
|
276
|
+
static VALUE slice(int argc, VALUE *argv, VALUE self)
|
277
|
+
{
|
278
|
+
VALUE arg ;
|
279
|
+
long beg, len ;
|
280
|
+
xmlNodeSetPtr node_set;
|
281
|
+
|
282
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
283
|
+
|
284
|
+
if (argc == 2) {
|
285
|
+
beg = NUM2LONG(argv[0]);
|
286
|
+
len = NUM2LONG(argv[1]);
|
287
|
+
if (beg < 0) {
|
288
|
+
beg += node_set->nodeNr ;
|
289
|
+
}
|
290
|
+
return subseq(self, beg, len);
|
291
|
+
}
|
292
|
+
|
293
|
+
if (argc != 1) {
|
294
|
+
rb_scan_args(argc, argv, "11", NULL, NULL);
|
295
|
+
}
|
296
|
+
arg = argv[0];
|
297
|
+
|
298
|
+
if (FIXNUM_P(arg)) {
|
299
|
+
return index_at(self, FIX2LONG(arg));
|
300
|
+
}
|
301
|
+
|
302
|
+
/* if arg is Range */
|
303
|
+
switch (rb_range_beg_len(arg, &beg, &len, (long)node_set->nodeNr, 0)) {
|
304
|
+
case Qfalse:
|
305
|
+
break;
|
306
|
+
case Qnil:
|
307
|
+
return Qnil;
|
308
|
+
default:
|
309
|
+
return subseq(self, beg, len);
|
310
|
+
}
|
311
|
+
|
312
|
+
return index_at(self, NUM2LONG(arg));
|
313
|
+
}
|
314
|
+
|
315
|
+
|
316
|
+
/*
|
317
|
+
* call-seq:
|
318
|
+
* to_a
|
319
|
+
*
|
320
|
+
* Return this list as an Array
|
321
|
+
*/
|
322
|
+
static VALUE to_array(VALUE self)
|
323
|
+
{
|
324
|
+
xmlNodeSetPtr node_set ;
|
325
|
+
VALUE list;
|
326
|
+
int i;
|
327
|
+
|
328
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
329
|
+
|
330
|
+
list = rb_ary_new2(node_set->nodeNr);
|
331
|
+
for(i = 0; i < node_set->nodeNr; i++) {
|
332
|
+
VALUE elt = Nokogiri_wrap_xml_node_set_node(node_set->nodeTab[i], self);
|
333
|
+
rb_ary_push( list, elt );
|
334
|
+
}
|
335
|
+
|
336
|
+
return list;
|
337
|
+
}
|
338
|
+
|
339
|
+
/*
|
340
|
+
* call-seq:
|
341
|
+
* unlink
|
342
|
+
*
|
343
|
+
* Unlink this NodeSet and all Node objects it contains from their current context.
|
344
|
+
*/
|
345
|
+
static VALUE unlink_nodeset(VALUE self)
|
346
|
+
{
|
347
|
+
xmlNodeSetPtr node_set;
|
348
|
+
int j, nodeNr ;
|
349
|
+
|
350
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
351
|
+
|
352
|
+
nodeNr = node_set->nodeNr ;
|
353
|
+
for (j = 0 ; j < nodeNr ; j++) {
|
354
|
+
if (! NOKOGIRI_NAMESPACE_EH(node_set->nodeTab[j])) {
|
355
|
+
VALUE node ;
|
356
|
+
xmlNodePtr node_ptr;
|
357
|
+
node = Nokogiri_wrap_xml_node(Qnil, node_set->nodeTab[j]);
|
358
|
+
rb_funcall(node, rb_intern("unlink"), 0); /* modifies the C struct out from under the object */
|
359
|
+
Data_Get_Struct(node, xmlNode, node_ptr);
|
360
|
+
node_set->nodeTab[j] = node_ptr ;
|
361
|
+
}
|
362
|
+
}
|
363
|
+
return self ;
|
364
|
+
}
|
365
|
+
|
366
|
+
|
367
|
+
static void reify_node_set_namespaces(VALUE self)
|
368
|
+
{
|
369
|
+
/*
|
370
|
+
* as mentioned in deallocate() above, xmlNs structs returned in an XPath
|
371
|
+
* NodeSet are duplicates, and we don't clean them up at deallocate() time.
|
372
|
+
*
|
373
|
+
* as a result, we need to make sure the Ruby manages this memory. we do this
|
374
|
+
* by forcing the creation of a Ruby object wrapped around the xmlNs.
|
375
|
+
*
|
376
|
+
* we also have to make sure that the NodeSet has a reference to the
|
377
|
+
* Namespace object, otherwise GC will kick in and the Namespace won't be
|
378
|
+
* marked.
|
379
|
+
*
|
380
|
+
* we *could* do this safely with *all* the nodes in the NodeSet, but we only
|
381
|
+
* *need* to do it for xmlNs structs, and so you get the code we have here.
|
382
|
+
*/
|
383
|
+
int j ;
|
384
|
+
xmlNodeSetPtr node_set ;
|
385
|
+
VALUE namespace_cache ;
|
386
|
+
|
387
|
+
Data_Get_Struct(self, xmlNodeSet, node_set);
|
388
|
+
|
389
|
+
namespace_cache = rb_iv_get(self, "@namespace_cache");
|
390
|
+
|
391
|
+
for (j = 0 ; j < node_set->nodeNr ; j++) {
|
392
|
+
if (NOKOGIRI_NAMESPACE_EH(node_set->nodeTab[j])) {
|
393
|
+
rb_ary_push(namespace_cache, Nokogiri_wrap_xml_node_set_node(node_set->nodeTab[j], self));
|
394
|
+
}
|
395
|
+
}
|
396
|
+
}
|
397
|
+
|
398
|
+
|
399
|
+
VALUE Nokogiri_wrap_xml_node_set(xmlNodeSetPtr node_set, VALUE document)
|
400
|
+
{
|
401
|
+
VALUE new_set ;
|
402
|
+
|
403
|
+
if (node_set == NULL) {
|
404
|
+
node_set = xmlXPathNodeSetCreate(NULL);
|
405
|
+
}
|
406
|
+
|
407
|
+
new_set = Data_Wrap_Struct(cNokogiriXmlNodeSet, 0, deallocate, node_set);
|
408
|
+
|
409
|
+
if (!NIL_P(document)) {
|
410
|
+
rb_iv_set(new_set, "@document", document);
|
411
|
+
rb_funcall(document, decorate, 1, new_set);
|
412
|
+
}
|
413
|
+
|
414
|
+
rb_iv_set(new_set, "@namespace_cache", rb_ary_new());
|
415
|
+
reify_node_set_namespaces(new_set);
|
416
|
+
|
417
|
+
return new_set ;
|
418
|
+
}
|
419
|
+
|
420
|
+
VALUE Nokogiri_wrap_xml_node_set_node(xmlNodePtr node, VALUE node_set)
|
421
|
+
{
|
422
|
+
xmlDocPtr document ;
|
423
|
+
|
424
|
+
if (NOKOGIRI_NAMESPACE_EH(node)) {
|
425
|
+
Data_Get_Struct(rb_iv_get(node_set, "@document"), xmlDoc, document);
|
426
|
+
return Nokogiri_wrap_xml_namespace(document, (xmlNsPtr)node);
|
427
|
+
} else {
|
428
|
+
return Nokogiri_wrap_xml_node(Qnil, node);
|
429
|
+
}
|
430
|
+
}
|
431
|
+
|
432
|
+
|
433
|
+
static void xpath_node_set_del(xmlNodeSetPtr cur, xmlNodePtr val)
|
434
|
+
{
|
435
|
+
/*
|
436
|
+
* as mentioned a few times above, we do not want to free xmlNs structs
|
437
|
+
* outside of the Namespace lifecycle.
|
438
|
+
*
|
439
|
+
* xmlXPathNodeSetDel() frees xmlNs structs, and so here we reproduce that
|
440
|
+
* function with the xmlNs logic.
|
441
|
+
*/
|
442
|
+
int i;
|
443
|
+
|
444
|
+
if (cur == NULL) return;
|
445
|
+
if (val == NULL) return;
|
446
|
+
|
447
|
+
/*
|
448
|
+
* find node in nodeTab
|
449
|
+
*/
|
450
|
+
for (i = 0;i < cur->nodeNr;i++)
|
451
|
+
if (cur->nodeTab[i] == val) break;
|
452
|
+
|
453
|
+
if (i >= cur->nodeNr) { /* not found */
|
454
|
+
return;
|
455
|
+
}
|
456
|
+
cur->nodeNr--;
|
457
|
+
for (;i < cur->nodeNr;i++)
|
458
|
+
cur->nodeTab[i] = cur->nodeTab[i + 1];
|
459
|
+
cur->nodeTab[cur->nodeNr] = NULL;
|
460
|
+
}
|
461
|
+
|
462
|
+
|
463
|
+
VALUE cNokogiriXmlNodeSet ;
|
464
|
+
void init_xml_node_set(void)
|
465
|
+
{
|
466
|
+
VALUE nokogiri = rb_define_module("Nokogiri");
|
467
|
+
VALUE xml = rb_define_module_under(nokogiri, "XML");
|
468
|
+
VALUE klass = rb_define_class_under(xml, "NodeSet", rb_cObject);
|
469
|
+
cNokogiriXmlNodeSet = klass;
|
470
|
+
|
471
|
+
rb_define_alloc_func(klass, allocate);
|
472
|
+
rb_define_method(klass, "length", length, 0);
|
473
|
+
rb_define_method(klass, "[]", slice, -1);
|
474
|
+
rb_define_method(klass, "slice", slice, -1);
|
475
|
+
rb_define_method(klass, "push", push, 1);
|
476
|
+
rb_define_method(klass, "|", set_union, 1);
|
477
|
+
rb_define_method(klass, "-", minus, 1);
|
478
|
+
rb_define_method(klass, "unlink", unlink_nodeset, 0);
|
479
|
+
rb_define_method(klass, "to_a", to_array, 0);
|
480
|
+
rb_define_method(klass, "dup", duplicate, 0);
|
481
|
+
rb_define_method(klass, "delete", delete, 1);
|
482
|
+
rb_define_method(klass, "&", intersection, 1);
|
483
|
+
rb_define_method(klass, "include?", include_eh, 1);
|
484
|
+
|
485
|
+
decorate = rb_intern("decorate");
|
486
|
+
}
|