libxml-ruby 0.9.1-x86-mswin32-60 → 0.9.2-x86-mswin32-60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,281 +1,294 @@
1
- /* $Id: ruby_xml_xpath_context.c 566 2008-11-18 06:53:36Z cfis $ */
2
-
3
- /* Please see the LICENSE file for copyright and distribution information */
4
-
5
- #include "ruby_libxml.h"
6
- #include "ruby_xml_xpath_context.h"
7
- #include <st.h>
8
-
9
-
10
- /*
11
- * Document-class: LibXML::XML::XPath::Context
12
- *
13
- * The XML::XPath::Context class is used to evaluate XPath
14
- * expressions. Generally, you should not directly use this class,
15
- * but instead use the XML::Document#find and XML::Node#find methods.
16
- *
17
- * doc = XML::Document.string('<header>content</header>')
18
- * context = XPath::Context.new(doc)
19
- * context.node = doc.root
20
- * context.register_namespaces_from_node(doc.root)
21
- * nodes = context.find('/header')
22
- */
23
-
24
- VALUE cXMLXPathContext;
25
-
26
- void
27
- ruby_xml_xpath_context_free(xmlXPathContextPtr ctxt) {
28
- xmlXPathFreeContext(ctxt);
29
- }
30
-
31
-
32
- VALUE
33
- ruby_xml_xpath_context_alloc(VALUE klass) {
34
- return Data_Wrap_Struct(cXMLXPathContext,
35
- NULL,
36
- ruby_xml_xpath_context_free,
37
- NULL);
38
- }
39
-
40
- /* call-seq:
41
- * XPath::Context.new(node) -> XPath::Context
42
- *
43
- * Creates a new XPath context for the specified document. The
44
- * context can then be used to evaluate an XPath expression.
45
- *
46
- * doc = XML::Document.string('<header><first>hi</first></header>')
47
- * context = XPath::Context.new(doc)
48
- * nodes = XPath::Object.new('//first', context)
49
- * nodes.length == 1
50
- */
51
- VALUE
52
- ruby_xml_xpath_context_initialize(VALUE self, VALUE node) {
53
- xmlDocPtr xdoc;
54
- VALUE document;
55
- #ifndef LIBXML_XPATH_ENABLED
56
- rb_raise(rb_eTypeError, "libxml was not compiled with XPath support.");
57
- #endif
58
-
59
- if (rb_obj_is_kind_of(node, cXMLNode) == Qtrue)
60
- {
61
- document = rb_funcall(node, rb_intern("doc"), 0);
62
- if NIL_P(document)
63
- rb_raise(rb_eTypeError, "Supplied node must belong to a document.");
64
- }
65
- else if (rb_obj_is_kind_of(node, cXMLDocument) == Qtrue)
66
- {
67
- document = node;
68
- }
69
- else
70
- {
71
- rb_raise(rb_eTypeError, "Supplied argument must be a document or node.");
72
- }
73
-
74
- Data_Get_Struct(document, xmlDoc, xdoc);
75
- DATA_PTR(self) = xmlXPathNewContext(xdoc);
76
-
77
- /* Save the doc as an attribute, this will expose it to Ruby's GC. */
78
- rb_iv_set(self, "@doc", document);
79
-
80
- return self;
81
- }
82
-
83
-
84
- /*
85
- * call-seq:
86
- * context.register_namespace(prefix, uri) -> (true|false)
87
- *
88
- * Register the specified namespace URI with the specified prefix
89
- * in this context.
90
-
91
- * context.register_namespace('xi', 'http://www.w3.org/2001/XInclude')
92
- */
93
- VALUE
94
- ruby_xml_xpath_context_register_namespace(VALUE self, VALUE prefix, VALUE uri) {
95
- xmlXPathContextPtr ctxt;
96
-
97
- Data_Get_Struct(self, xmlXPathContext, ctxt);
98
- if (xmlXPathRegisterNs(ctxt,
99
- (xmlChar*)StringValuePtr(prefix),
100
- (xmlChar*)StringValuePtr(uri))
101
- == 0) {
102
- return(Qtrue);
103
- } else {
104
- /* Should raise an exception, IMHO (whose?, why shouldnt it? -danj)*/
105
- rb_warning("register namespace failed");
106
- return(Qfalse);
107
- }
108
- }
109
-
110
- /* call-seq:
111
- * context.register_namespaces_from_node(node) -> self
112
- *
113
- * Helper method to read in namespaces defined on a node.
114
- *
115
- * doc = XML::Document.string('<header><first>hi</first></header>')
116
- * context = XPath::Context.new(doc)
117
- * context.register_namespaces_from_node(doc.root)
118
- */
119
- VALUE
120
- ruby_xml_xpath_context_register_namespaces_from_node(VALUE self, VALUE node) {
121
- xmlXPathContextPtr xctxt;
122
- xmlNodePtr xnode;
123
- xmlNsPtr *xnsArr;
124
-
125
- Data_Get_Struct(self, xmlXPathContext, xctxt);
126
-
127
- if (rb_obj_is_kind_of(node, cXMLDocument) == Qtrue)
128
- {
129
- xmlDocPtr xdoc;
130
- Data_Get_Struct(node, xmlDoc, xdoc);
131
- xnode = xmlDocGetRootElement(xdoc);
132
- }
133
- else if (rb_obj_is_kind_of(node, cXMLNode) == Qtrue)
134
- {
135
- Data_Get_Struct(node, xmlNode, xnode);
136
- }
137
- else
138
- {
139
- rb_raise(rb_eTypeError, "The first argument must be a document or node.");
140
- }
141
-
142
- xnsArr = xmlGetNsList(xnode->doc, xnode);
143
-
144
- if (xnsArr)
145
- {
146
- xmlNsPtr xns = *xnsArr;
147
-
148
- while (xns) {
149
- /* If there is no prefix, then this is the default namespace.
150
- Skip it for now. */
151
- if (xns->prefix)
152
- {
153
- VALUE prefix = rb_str_new2(xns->prefix);
154
- VALUE uri = rb_str_new2(xns->href);
155
- ruby_xml_xpath_context_register_namespace(self, prefix, uri);
156
- }
157
- xns = xns->next;
158
- }
159
- xmlFree(xnsArr);
160
- }
161
-
162
- return self;
163
- }
164
-
165
- static int
166
- iterate_ns_hash(st_data_t prefix, st_data_t uri, st_data_t self)
167
- {
168
- ruby_xml_xpath_context_register_namespace(self, prefix, uri);
169
- return ST_CONTINUE;
170
- }
171
-
172
-
173
- /*
174
- * call-seq:
175
- * context.register_namespaces(["prefix:uri"]) -> self
176
- *
177
- * Register the specified namespaces in this context.
178
- *
179
- * context.register_namespaces('xi:http://www.w3.org/2001/XInclude')
180
- * context.register_namespaces(['xlink:http://www.w3.org/1999/xlink',
181
- * 'xi:http://www.w3.org/2001/XInclude')
182
- * context.register_namespaces('xlink' => 'http://www.w3.org/1999/xlink',
183
- * 'xi' => 'http://www.w3.org/2001/XInclude')
184
- */
185
- VALUE
186
- ruby_xml_xpath_context_register_namespaces(VALUE self, VALUE nslist) {
187
- char *cp;
188
- long i;
189
- VALUE rprefix, ruri;
190
-
191
- /* Need to loop through the 2nd argument and iterate through the
192
- * list of namespaces that we want to allow */
193
- switch (TYPE(nslist)) {
194
- case T_STRING:
195
- cp = strchr(StringValuePtr(nslist), (int)':');
196
- if (cp == NULL) {
197
- rprefix = nslist;
198
- ruri = Qnil;
199
- } else {
200
- rprefix = rb_str_new(StringValuePtr(nslist), (int)((long)cp - (long)StringValuePtr(nslist)));
201
- ruri = rb_str_new2(&cp[1]);
202
- }
203
- /* Should test the results of this */
204
- ruby_xml_xpath_context_register_namespace(self, rprefix, ruri);
205
- break;
206
- case T_ARRAY:
207
- for (i = 0; i < RARRAY(nslist)->len; i++) {
208
- ruby_xml_xpath_context_register_namespaces(self, RARRAY(nslist)->ptr[i]);
209
- }
210
- break;
211
- case T_HASH:
212
- st_foreach(RHASH(nslist)->tbl, iterate_ns_hash, self);
213
- break;
214
- default:
215
- rb_raise(rb_eArgError, "Invalid argument type, only accept string, array of strings, or an array of arrays");
216
- }
217
- return self;
218
- }
219
-
220
- /*
221
- * call-seq:
222
- * context.node = node
223
- *
224
- * Set the current node used by the XPath engine
225
-
226
- * doc = XML::Document.string('<header><first>hi</first></header>')
227
- * context.node = doc.root.first
228
- */
229
- VALUE
230
- ruby_xml_xpath_context_node_set(VALUE self, VALUE node) {
231
- xmlXPathContextPtr xctxt;
232
- xmlNodePtr xnode;
233
-
234
- Data_Get_Struct(self, xmlXPathContext, xctxt);
235
- Data_Get_Struct(node, xmlNode, xnode);
236
- xctxt->node = xnode;
237
- return node;
238
- }
239
-
240
- /*
241
- * call-seq:
242
- * context.find("xpath") -> XML::XPath::Object
243
- *
244
- * Find nodes matching the specified XPath expression
245
- */
246
- VALUE
247
- ruby_xml_xpath_context_find(VALUE self, VALUE xpath_expr) {
248
- xmlXPathContextPtr xctxt;
249
- xmlXPathObjectPtr xobject;
250
- VALUE result;
251
-
252
- Data_Get_Struct(self, xmlXPathContext, xctxt);
253
- xobject = xmlXPathEval((xmlChar*)StringValuePtr(xpath_expr), xctxt);
254
-
255
- if (xobject == NULL)
256
- {
257
- /* xmlLastError is differnet than xctxt->lastError. Use
258
- xmlLastError since it has the message set while xctxt->lastError
259
- does not. */
260
- xmlErrorPtr xerror = xmlGetLastError();
261
- ruby_xml_raise(xerror);
262
- }
263
-
264
- result = ruby_xml_xpath_object_wrap(xobject);
265
- rb_iv_set(result, "@context", self);
266
- return result;
267
- }
268
-
269
-
270
- void
271
- ruby_init_xml_xpath_context(void) {
272
- cXMLXPathContext = rb_define_class_under(mXPath, "Context", rb_cObject);
273
- rb_define_alloc_func(cXMLXPathContext, ruby_xml_xpath_context_alloc);
274
- rb_define_attr(cXMLXPathContext, "doc", 1, 0);
275
- rb_define_method(cXMLXPathContext, "initialize", ruby_xml_xpath_context_initialize, 1);
276
- rb_define_method(cXMLXPathContext, "register_namespaces", ruby_xml_xpath_context_register_namespaces, 1);
277
- rb_define_method(cXMLXPathContext, "register_namespaces_from_node", ruby_xml_xpath_context_register_namespaces_from_node, 1);
278
- rb_define_method(cXMLXPathContext, "register_namespace", ruby_xml_xpath_context_register_namespace, 2);
279
- rb_define_method(cXMLXPathContext, "node=", ruby_xml_xpath_context_node_set, 1);
280
- rb_define_method(cXMLXPathContext, "find", ruby_xml_xpath_context_find, 1);
281
- }
1
+ /* $Id: ruby_xml_xpath_context.c 600 2008-11-19 07:39:29Z cfis $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ #include "ruby_libxml.h"
6
+ #include "ruby_xml_xpath_context.h"
7
+ #include "ruby_xml_xpath_expression.h"
8
+ #include <st.h>
9
+
10
+
11
+ /*
12
+ * Document-class: LibXML::XML::XPath::Context
13
+ *
14
+ * The XML::XPath::Context class is used to evaluate XPath
15
+ * expressions. Generally, you should not directly use this class,
16
+ * but instead use the XML::Document#find and XML::Node#find methods.
17
+ *
18
+ * doc = XML::Document.string('<header>content</header>')
19
+ * context = XPath::Context.new(doc)
20
+ * context.node = doc.root
21
+ * context.register_namespaces_from_node(doc.root)
22
+ * nodes = context.find('/header')
23
+ */
24
+
25
+ VALUE cXMLXPathContext;
26
+
27
+ void
28
+ ruby_xml_xpath_context_free(xmlXPathContextPtr ctxt) {
29
+ xmlXPathFreeContext(ctxt);
30
+ }
31
+
32
+
33
+ VALUE
34
+ ruby_xml_xpath_context_alloc(VALUE klass) {
35
+ return Data_Wrap_Struct(cXMLXPathContext,
36
+ NULL,
37
+ ruby_xml_xpath_context_free,
38
+ NULL);
39
+ }
40
+
41
+ /* call-seq:
42
+ * XPath::Context.new(node) -> XPath::Context
43
+ *
44
+ * Creates a new XPath context for the specified document. The
45
+ * context can then be used to evaluate an XPath expression.
46
+ *
47
+ * doc = XML::Document.string('<header><first>hi</first></header>')
48
+ * context = XPath::Context.new(doc)
49
+ * nodes = XPath::Object.new('//first', context)
50
+ * nodes.length == 1
51
+ */
52
+ VALUE
53
+ ruby_xml_xpath_context_initialize(VALUE self, VALUE node) {
54
+ xmlDocPtr xdoc;
55
+ VALUE document;
56
+ #ifndef LIBXML_XPATH_ENABLED
57
+ rb_raise(rb_eTypeError, "libxml was not compiled with XPath support.");
58
+ #endif
59
+
60
+ if (rb_obj_is_kind_of(node, cXMLNode) == Qtrue)
61
+ {
62
+ document = rb_funcall(node, rb_intern("doc"), 0);
63
+ if NIL_P(document)
64
+ rb_raise(rb_eTypeError, "Supplied node must belong to a document.");
65
+ }
66
+ else if (rb_obj_is_kind_of(node, cXMLDocument) == Qtrue)
67
+ {
68
+ document = node;
69
+ }
70
+ else
71
+ {
72
+ rb_raise(rb_eTypeError, "Supplied argument must be a document or node.");
73
+ }
74
+
75
+ Data_Get_Struct(document, xmlDoc, xdoc);
76
+ DATA_PTR(self) = xmlXPathNewContext(xdoc);
77
+
78
+ /* Save the doc as an attribute, this will expose it to Ruby's GC. */
79
+ rb_iv_set(self, "@doc", document);
80
+
81
+ return self;
82
+ }
83
+
84
+
85
+ /*
86
+ * call-seq:
87
+ * context.register_namespace(prefix, uri) -> (true|false)
88
+ *
89
+ * Register the specified namespace URI with the specified prefix
90
+ * in this context.
91
+
92
+ * context.register_namespace('xi', 'http://www.w3.org/2001/XInclude')
93
+ */
94
+ VALUE
95
+ ruby_xml_xpath_context_register_namespace(VALUE self, VALUE prefix, VALUE uri) {
96
+ xmlXPathContextPtr ctxt;
97
+
98
+ Data_Get_Struct(self, xmlXPathContext, ctxt);
99
+ if (xmlXPathRegisterNs(ctxt,
100
+ (xmlChar*)StringValuePtr(prefix),
101
+ (xmlChar*)StringValuePtr(uri))
102
+ == 0) {
103
+ return(Qtrue);
104
+ } else {
105
+ /* Should raise an exception, IMHO (whose?, why shouldnt it? -danj)*/
106
+ rb_warning("register namespace failed");
107
+ return(Qfalse);
108
+ }
109
+ }
110
+
111
+ /* call-seq:
112
+ * context.register_namespaces_from_node(node) -> self
113
+ *
114
+ * Helper method to read in namespaces defined on a node.
115
+ *
116
+ * doc = XML::Document.string('<header><first>hi</first></header>')
117
+ * context = XPath::Context.new(doc)
118
+ * context.register_namespaces_from_node(doc.root)
119
+ */
120
+ VALUE
121
+ ruby_xml_xpath_context_register_namespaces_from_node(VALUE self, VALUE node) {
122
+ xmlXPathContextPtr xctxt;
123
+ xmlNodePtr xnode;
124
+ xmlNsPtr *xnsArr;
125
+
126
+ Data_Get_Struct(self, xmlXPathContext, xctxt);
127
+
128
+ if (rb_obj_is_kind_of(node, cXMLDocument) == Qtrue)
129
+ {
130
+ xmlDocPtr xdoc;
131
+ Data_Get_Struct(node, xmlDoc, xdoc);
132
+ xnode = xmlDocGetRootElement(xdoc);
133
+ }
134
+ else if (rb_obj_is_kind_of(node, cXMLNode) == Qtrue)
135
+ {
136
+ Data_Get_Struct(node, xmlNode, xnode);
137
+ }
138
+ else
139
+ {
140
+ rb_raise(rb_eTypeError, "The first argument must be a document or node.");
141
+ }
142
+
143
+ xnsArr = xmlGetNsList(xnode->doc, xnode);
144
+
145
+ if (xnsArr)
146
+ {
147
+ xmlNsPtr xns = *xnsArr;
148
+
149
+ while (xns) {
150
+ /* If there is no prefix, then this is the default namespace.
151
+ Skip it for now. */
152
+ if (xns->prefix)
153
+ {
154
+ VALUE prefix = rb_str_new2(xns->prefix);
155
+ VALUE uri = rb_str_new2(xns->href);
156
+ ruby_xml_xpath_context_register_namespace(self, prefix, uri);
157
+ }
158
+ xns = xns->next;
159
+ }
160
+ xmlFree(xnsArr);
161
+ }
162
+
163
+ return self;
164
+ }
165
+
166
+ static int
167
+ iterate_ns_hash(st_data_t prefix, st_data_t uri, st_data_t self)
168
+ {
169
+ ruby_xml_xpath_context_register_namespace(self, prefix, uri);
170
+ return ST_CONTINUE;
171
+ }
172
+
173
+
174
+ /*
175
+ * call-seq:
176
+ * context.register_namespaces(["prefix:uri"]) -> self
177
+ *
178
+ * Register the specified namespaces in this context.
179
+ *
180
+ * context.register_namespaces('xi:http://www.w3.org/2001/XInclude')
181
+ * context.register_namespaces(['xlink:http://www.w3.org/1999/xlink',
182
+ * 'xi:http://www.w3.org/2001/XInclude')
183
+ * context.register_namespaces('xlink' => 'http://www.w3.org/1999/xlink',
184
+ * 'xi' => 'http://www.w3.org/2001/XInclude')
185
+ */
186
+ VALUE
187
+ ruby_xml_xpath_context_register_namespaces(VALUE self, VALUE nslist) {
188
+ char *cp;
189
+ long i;
190
+ VALUE rprefix, ruri;
191
+
192
+ /* Need to loop through the 2nd argument and iterate through the
193
+ * list of namespaces that we want to allow */
194
+ switch (TYPE(nslist)) {
195
+ case T_STRING:
196
+ cp = strchr(StringValuePtr(nslist), (int)':');
197
+ if (cp == NULL) {
198
+ rprefix = nslist;
199
+ ruri = Qnil;
200
+ } else {
201
+ rprefix = rb_str_new(StringValuePtr(nslist), (int)((long)cp - (long)StringValuePtr(nslist)));
202
+ ruri = rb_str_new2(&cp[1]);
203
+ }
204
+ /* Should test the results of this */
205
+ ruby_xml_xpath_context_register_namespace(self, rprefix, ruri);
206
+ break;
207
+ case T_ARRAY:
208
+ for (i = 0; i < RARRAY(nslist)->len; i++) {
209
+ ruby_xml_xpath_context_register_namespaces(self, RARRAY(nslist)->ptr[i]);
210
+ }
211
+ break;
212
+ case T_HASH:
213
+ st_foreach(RHASH(nslist)->tbl, iterate_ns_hash, self);
214
+ break;
215
+ default:
216
+ rb_raise(rb_eArgError, "Invalid argument type, only accept string, array of strings, or an array of arrays");
217
+ }
218
+ return self;
219
+ }
220
+
221
+ /*
222
+ * call-seq:
223
+ * context.node = node
224
+ *
225
+ * Set the current node used by the XPath engine
226
+
227
+ * doc = XML::Document.string('<header><first>hi</first></header>')
228
+ * context.node = doc.root.first
229
+ */
230
+ VALUE
231
+ ruby_xml_xpath_context_node_set(VALUE self, VALUE node) {
232
+ xmlXPathContextPtr xctxt;
233
+ xmlNodePtr xnode;
234
+
235
+ Data_Get_Struct(self, xmlXPathContext, xctxt);
236
+ Data_Get_Struct(node, xmlNode, xnode);
237
+ xctxt->node = xnode;
238
+ return node;
239
+ }
240
+
241
+ /*
242
+ * call-seq:
243
+ * context.find("xpath") -> XML::XPath::Object
244
+ *
245
+ * Find nodes matching the specified XPath expression
246
+ */
247
+ VALUE
248
+ ruby_xml_xpath_context_find(VALUE self, VALUE xpath_expr) {
249
+ xmlXPathContextPtr xctxt;
250
+ xmlXPathObjectPtr xobject;
251
+ xmlXPathCompExprPtr xcompexpr;
252
+ VALUE result;
253
+
254
+ Data_Get_Struct(self, xmlXPathContext, xctxt);
255
+
256
+ if (TYPE(xpath_expr) == T_STRING) {
257
+ VALUE expression = rb_check_string_type(xpath_expr);
258
+ xobject = xmlXPathEval((xmlChar*)StringValueCStr(expression), xctxt);
259
+ }
260
+ else if (rb_obj_is_kind_of(xpath_expr, cXMLXPathExpression)) {
261
+ Data_Get_Struct(xpath_expr, xmlXPathCompExpr, xcompexpr);
262
+ xobject = xmlXPathCompiledEval(xcompexpr, xctxt);
263
+ }
264
+ else {
265
+ rb_raise(rb_eTypeError, "Argument should be an intance of a String or XPath::Expression");
266
+ }
267
+
268
+ if (xobject == NULL)
269
+ {
270
+ /* xmlLastError is different than xctxt->lastError. Use
271
+ xmlLastError since it has the message set while xctxt->lastError
272
+ does not. */
273
+ xmlErrorPtr xerror = xmlGetLastError();
274
+ ruby_xml_raise(xerror);
275
+ }
276
+
277
+ result = ruby_xml_xpath_object_wrap(xobject);
278
+ rb_iv_set(result, "@context", self);
279
+ return result;
280
+ }
281
+
282
+
283
+ void
284
+ ruby_init_xml_xpath_context(void) {
285
+ cXMLXPathContext = rb_define_class_under(mXPath, "Context", rb_cObject);
286
+ rb_define_alloc_func(cXMLXPathContext, ruby_xml_xpath_context_alloc);
287
+ rb_define_attr(cXMLXPathContext, "doc", 1, 0);
288
+ rb_define_method(cXMLXPathContext, "initialize", ruby_xml_xpath_context_initialize, 1);
289
+ rb_define_method(cXMLXPathContext, "register_namespaces", ruby_xml_xpath_context_register_namespaces, 1);
290
+ rb_define_method(cXMLXPathContext, "register_namespaces_from_node", ruby_xml_xpath_context_register_namespaces_from_node, 1);
291
+ rb_define_method(cXMLXPathContext, "register_namespace", ruby_xml_xpath_context_register_namespace, 2);
292
+ rb_define_method(cXMLXPathContext, "node=", ruby_xml_xpath_context_node_set, 1);
293
+ rb_define_method(cXMLXPathContext, "find", ruby_xml_xpath_context_find, 1);
294
+ }