ruby-xml-smart 0.1.11-i486-linux
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +4 -0
- data/COPYING +504 -0
- data/Changelog +192 -0
- data/README +52 -0
- data/Rakefile +112 -0
- data/TODO +6 -0
- data/examples/EXAMPLE.xml +17 -0
- data/examples/EXAMPLE.xml.sic +17 -0
- data/examples/Visualise/EXAMPLE.xml +18 -0
- data/examples/Visualise/term-ansicolor-0.0.4/CHANGES +11 -0
- data/examples/Visualise/term-ansicolor-0.0.4/GPL +340 -0
- data/examples/Visualise/term-ansicolor-0.0.4/README.en +23 -0
- data/examples/Visualise/term-ansicolor-0.0.4/Rakefile +72 -0
- data/examples/Visualise/term-ansicolor-0.0.4/VERSION +1 -0
- data/examples/Visualise/term-ansicolor-0.0.4/examples/cdiff.rb +20 -0
- data/examples/Visualise/term-ansicolor-0.0.4/examples/example.rb +82 -0
- data/examples/Visualise/term-ansicolor-0.0.4/install.rb +12 -0
- data/examples/Visualise/term-ansicolor-0.0.4/lib/term/ansicolor.rb +78 -0
- data/examples/Visualise/xpath_visual.rb +45 -0
- data/examples/add_children.rb +14 -0
- data/examples/add_elements.rb +13 -0
- data/examples/attrs.rb +15 -0
- data/examples/children.rb +14 -0
- data/examples/concurrent.rb +30 -0
- data/examples/copy.rb +23 -0
- data/examples/create.rb +18 -0
- data/examples/delete.rb +30 -0
- data/examples/move_elements.rb +12 -0
- data/examples/namespace.rb +14 -0
- data/examples/namespace_detailed.rb +36 -0
- data/examples/namespace_find.rb +20 -0
- data/examples/pull.rb +18 -0
- data/examples/qname.rb +16 -0
- data/examples/replace.rb +14 -0
- data/examples/set_OR_replace.rb +32 -0
- data/examples/signals.rb +28 -0
- data/examples/string.rb +27 -0
- data/examples/write.rb +11 -0
- data/examples/xpath_attrs.rb +19 -0
- data/examples/xpath_functions.rb +7 -0
- data/examples/xpath_root.rb +6 -0
- data/extconf.rb +29 -0
- data/rbxs.c +136 -0
- data/rbxs.h +53 -0
- data/rbxs_dom.c +483 -0
- data/rbxs_dom.h +32 -0
- data/rbxs_domattribute.c +189 -0
- data/rbxs_domattribute.h +18 -0
- data/rbxs_domattributeset.c +182 -0
- data/rbxs_domattributeset.h +17 -0
- data/rbxs_domelement.c +656 -0
- data/rbxs_domelement.h +18 -0
- data/rbxs_domnamespace.c +127 -0
- data/rbxs_domnamespace.h +18 -0
- data/rbxs_domnamespaceset.c +276 -0
- data/rbxs_domnamespaceset.h +17 -0
- data/rbxs_domnodeset.c +284 -0
- data/rbxs_domnodeset.h +19 -0
- data/rbxs_domother.c +121 -0
- data/rbxs_domother.h +18 -0
- data/rbxs_domtext.c +165 -0
- data/rbxs_domtext.h +18 -0
- data/rbxs_pull.c +244 -0
- data/rbxs_pull.h +17 -0
- data/rbxs_pullattribute.c +124 -0
- data/rbxs_pullattribute.h +18 -0
- data/rbxs_pullattributeset.c +156 -0
- data/rbxs_pullattributeset.h +17 -0
- data/rbxs_qname.c +267 -0
- data/rbxs_qname.h +18 -0
- data/rbxs_utils.h +39 -0
- data/test/namespace_test.rb +83 -0
- metadata +125 -0
data/rbxs_domelement.c
ADDED
@@ -0,0 +1,656 @@
|
|
1
|
+
#include "rbxs_qname.h"
|
2
|
+
#include "rbxs_dom.h"
|
3
|
+
#include "rbxs_domelement.h"
|
4
|
+
#include "rbxs_domnodeset.h"
|
5
|
+
#include "rbxs_domattribute.h"
|
6
|
+
#include "rbxs_domattributeset.h"
|
7
|
+
#include "rbxs_domnamespace.h"
|
8
|
+
#include "rbxs_domnamespaceset.h"
|
9
|
+
#include "rbxs_domtext.h"
|
10
|
+
|
11
|
+
VALUE cSmartDomElement;
|
12
|
+
|
13
|
+
/* -- */
|
14
|
+
// ***********************************************************************************
|
15
|
+
// GC
|
16
|
+
// ***********************************************************************************
|
17
|
+
void rbxs_domelement_free(rbxs_domelement *prbxs_domelement) {
|
18
|
+
if (prbxs_domelement != NULL) {
|
19
|
+
free(prbxs_domelement);
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
void rbxs_domelement_mark(rbxs_domelement *prbxs_domelement) {
|
24
|
+
if (prbxs_domelement == NULL) return;
|
25
|
+
if (!NIL_P(prbxs_domelement->doc)) rb_gc_mark(prbxs_domelement->doc);
|
26
|
+
}
|
27
|
+
|
28
|
+
// ***********************************************************************************
|
29
|
+
// Methods
|
30
|
+
// ***********************************************************************************
|
31
|
+
/* ++ */
|
32
|
+
|
33
|
+
/*
|
34
|
+
* Documentation
|
35
|
+
*/
|
36
|
+
VALUE rbxs_domelement_replace_by(VALUE self, VALUE element)
|
37
|
+
{
|
38
|
+
rbxs_domelement *prbxs_domelementA, *prbxs_domelementB;
|
39
|
+
xmlNodePtr node;
|
40
|
+
|
41
|
+
if (rb_obj_is_kind_of(element, cSmartDomElement)) {
|
42
|
+
Data_Get_Struct(self, rbxs_domelement, prbxs_domelementA);
|
43
|
+
Data_Get_Struct(element, rbxs_domelement, prbxs_domelementB);
|
44
|
+
node = xmlCopyNode(prbxs_domelementB->node,1); // 1 == deep
|
45
|
+
node = xmlReplaceNode(prbxs_domelementA->node,node);
|
46
|
+
xmlUnlinkNode(prbxs_domelementA->node);
|
47
|
+
xmlFreeNode(prbxs_domelementA->node);
|
48
|
+
prbxs_domelementA->node = node;
|
49
|
+
if (node)
|
50
|
+
return(rbxs_domelement_new(cSmartDomElement, self, node));
|
51
|
+
} else
|
52
|
+
rb_raise(rb_eArgError, "takes an element as argument");
|
53
|
+
return(Qnil);
|
54
|
+
}
|
55
|
+
|
56
|
+
/*
|
57
|
+
* Documentation
|
58
|
+
*/
|
59
|
+
VALUE rbxs_domelement_dump(VALUE self)
|
60
|
+
{
|
61
|
+
rbxs_domelement *prbxs_domelement;
|
62
|
+
xmlBufferPtr result;
|
63
|
+
VALUE ret;
|
64
|
+
|
65
|
+
Data_Get_Struct(self, rbxs_domelement, prbxs_domelement);
|
66
|
+
result = xmlBufferCreate();
|
67
|
+
xmlNodeDump(result, prbxs_domelement->node->doc, prbxs_domelement->node, 0, 1);
|
68
|
+
ret = rb_str_new2((char *)result->content);
|
69
|
+
|
70
|
+
xmlBufferFree(result);
|
71
|
+
return(ret);
|
72
|
+
}
|
73
|
+
|
74
|
+
static int nslist_each(VALUE key, VALUE value, xmlXPathContextPtr arg) {
|
75
|
+
if (xmlXPathRegisterNs(arg,(unsigned char *)StringValuePtr(key),(unsigned char *)StringValuePtr(value)) != 0) {
|
76
|
+
xmlXPathFreeContext(arg);
|
77
|
+
rb_raise(rb_eRuntimeError, "Couldn't add namespace");
|
78
|
+
}
|
79
|
+
return ST_CONTINUE;
|
80
|
+
}
|
81
|
+
|
82
|
+
/*
|
83
|
+
* Documentation
|
84
|
+
*/
|
85
|
+
VALUE rbxs_domelement_find(int argc, VALUE *argv, VALUE self)
|
86
|
+
{
|
87
|
+
rbxs_domelement *prbxs_domelement;
|
88
|
+
rbxs_dom *prbxs_dom;
|
89
|
+
xmlXPathContextPtr ctxt;
|
90
|
+
xmlXPathObjectPtr obj;
|
91
|
+
VALUE set;
|
92
|
+
|
93
|
+
if (argc > 2 || argc < 1)
|
94
|
+
rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
|
95
|
+
Check_Type(argv[0], T_STRING);
|
96
|
+
|
97
|
+
Data_Get_Struct(self, rbxs_domelement, prbxs_domelement);
|
98
|
+
Data_Get_Struct(prbxs_domelement->doc, rbxs_dom, prbxs_dom);
|
99
|
+
|
100
|
+
ctxt = xmlXPathNewContext(prbxs_domelement->node->doc);
|
101
|
+
if(ctxt == NULL)
|
102
|
+
rb_raise(rb_eRuntimeError, "Couldn't create XPath context");
|
103
|
+
ctxt->node = prbxs_domelement->node;
|
104
|
+
|
105
|
+
if (argc == 2) {
|
106
|
+
Check_Type(argv[1], T_HASH);
|
107
|
+
if (!RHASH_EMPTY_P(argv[1]))
|
108
|
+
rb_hash_foreach(argv[1], nslist_each, (st_data_t)ctxt);
|
109
|
+
}
|
110
|
+
if (!RHASH_EMPTY_P(prbxs_dom->namespaces))
|
111
|
+
rb_hash_foreach(prbxs_dom->namespaces, nslist_each, (st_data_t)ctxt);
|
112
|
+
|
113
|
+
obj = xmlXPathEvalExpression((unsigned char *)StringValuePtr(argv[0]), ctxt);
|
114
|
+
if(obj == NULL) {
|
115
|
+
xmlXPathFreeContext(ctxt);
|
116
|
+
rb_raise(rb_eRuntimeError, "Error in xpath");
|
117
|
+
}
|
118
|
+
switch (obj->type) {
|
119
|
+
case XPATH_NODESET:
|
120
|
+
set = rbxs_domnodeset_new(cSmartDomNodeSet,prbxs_domelement->doc,obj);
|
121
|
+
break;
|
122
|
+
case XPATH_BOOLEAN:
|
123
|
+
set = obj->boolval > 0 ? Qtrue : Qfalse;
|
124
|
+
xmlXPathFreeObject(obj);
|
125
|
+
break;
|
126
|
+
case XPATH_NUMBER:
|
127
|
+
set = rb_float_new(obj->floatval);
|
128
|
+
xmlXPathFreeObject(obj);
|
129
|
+
break;
|
130
|
+
case XPATH_STRING:
|
131
|
+
set = rb_str_new2((char *)obj->stringval);
|
132
|
+
xmlXPathFreeObject(obj);
|
133
|
+
break;
|
134
|
+
default:
|
135
|
+
set = Qnil;
|
136
|
+
}
|
137
|
+
xmlXPathFreeContext(ctxt);
|
138
|
+
|
139
|
+
return set;
|
140
|
+
}
|
141
|
+
|
142
|
+
/*
|
143
|
+
* Returns a XML::Smart::Dom::NodeSet containing all the
|
144
|
+
* children of this node.
|
145
|
+
*/
|
146
|
+
/*
|
147
|
+
* Documentation
|
148
|
+
*/
|
149
|
+
VALUE rbxs_domelement_children(VALUE self)
|
150
|
+
{
|
151
|
+
VALUE *vargv, obj;
|
152
|
+
vargv = ALLOC_N(VALUE, 1);
|
153
|
+
vargv[0] = rb_str_new2("*|text()");
|
154
|
+
obj = rbxs_domelement_find(1,vargv,self);
|
155
|
+
free(vargv);
|
156
|
+
return(obj);
|
157
|
+
}
|
158
|
+
|
159
|
+
/*
|
160
|
+
* Does this node have children? Return True or False.
|
161
|
+
*/
|
162
|
+
/*
|
163
|
+
* Documentation
|
164
|
+
*/
|
165
|
+
VALUE rbxs_domelement_children_q(VALUE self)
|
166
|
+
{
|
167
|
+
rbxs_domelement *prbxs_domelement;
|
168
|
+
|
169
|
+
Data_Get_Struct(self, rbxs_domelement, prbxs_domelement);
|
170
|
+
if (prbxs_domelement->node->children)
|
171
|
+
return(Qtrue);
|
172
|
+
else
|
173
|
+
return(Qfalse);
|
174
|
+
}
|
175
|
+
/*
|
176
|
+
* Documentation
|
177
|
+
*/
|
178
|
+
VALUE rbxs_domelement_children_empty_q(VALUE self)
|
179
|
+
{
|
180
|
+
return(rbxs_domelement_children_q(self) == Qtrue ? Qfalse : Qtrue);
|
181
|
+
}
|
182
|
+
/*
|
183
|
+
* Documentation
|
184
|
+
*/
|
185
|
+
VALUE rbxs_domelement_children_mixed_q(VALUE self)
|
186
|
+
{
|
187
|
+
rbxs_domelement *prbxs_domelement;
|
188
|
+
xmlNodePtr node;
|
189
|
+
|
190
|
+
Data_Get_Struct(self, rbxs_domelement, prbxs_domelement);
|
191
|
+
node = prbxs_domelement->node->children;
|
192
|
+
while (node != NULL) {
|
193
|
+
if (node->type == XML_TEXT_NODE) return(Qtrue);
|
194
|
+
node = node->next;
|
195
|
+
}
|
196
|
+
return(Qfalse);
|
197
|
+
}
|
198
|
+
|
199
|
+
/*
|
200
|
+
* Documentation
|
201
|
+
*/
|
202
|
+
VALUE rbxs_domelement_name(VALUE self)
|
203
|
+
{
|
204
|
+
return(rbxs_qname_new(cSmartQName,self,RBXS_PARSER_TYPE_DOM));
|
205
|
+
}
|
206
|
+
|
207
|
+
/*
|
208
|
+
* Documentation
|
209
|
+
*/
|
210
|
+
VALUE rbxs_domelement_parent(VALUE self)
|
211
|
+
{
|
212
|
+
rbxs_domelement *prbxs_domelement;
|
213
|
+
Data_Get_Struct(self, rbxs_domelement, prbxs_domelement);
|
214
|
+
|
215
|
+
if (prbxs_domelement->node != xmlDocGetRootElement(prbxs_domelement->node->doc))
|
216
|
+
return(rbxs_domelement_new(cSmartDomElement, prbxs_domelement->doc, prbxs_domelement->node->parent));
|
217
|
+
else
|
218
|
+
return(Qnil);
|
219
|
+
}
|
220
|
+
|
221
|
+
/*
|
222
|
+
* Documentation
|
223
|
+
*/
|
224
|
+
VALUE rbxs_domelement_path(VALUE self)
|
225
|
+
{
|
226
|
+
rbxs_domelement *prbxs_domelement;
|
227
|
+
xmlChar *ret;
|
228
|
+
VALUE val;
|
229
|
+
|
230
|
+
Data_Get_Struct(self, rbxs_domelement, prbxs_domelement);
|
231
|
+
ret = xmlGetNodePath(prbxs_domelement->node);
|
232
|
+
val = rb_str_new2((char *)ret);
|
233
|
+
xmlFree(ret);
|
234
|
+
return(val);
|
235
|
+
}
|
236
|
+
|
237
|
+
/*
|
238
|
+
* Documentation
|
239
|
+
*/
|
240
|
+
VALUE rbxs_domelement_text_set(VALUE self, VALUE text)
|
241
|
+
{
|
242
|
+
rbxs_domelement *prbxs_domelement;
|
243
|
+
rbxs_dom *prbxs_dom;
|
244
|
+
unsigned char *tc;
|
245
|
+
VALUE str;
|
246
|
+
|
247
|
+
Data_Get_Struct(self, rbxs_domelement, prbxs_domelement);
|
248
|
+
Data_Get_Struct(prbxs_domelement->doc, rbxs_dom, prbxs_dom);
|
249
|
+
|
250
|
+
str = rb_obj_as_string(text);
|
251
|
+
if (NIL_P(str) || TYPE(str) != T_STRING)
|
252
|
+
rb_raise(rb_eTypeError, "cannot convert obj to string");
|
253
|
+
tc = (unsigned char *)StringValuePtr(str);
|
254
|
+
if (!xmlCheckUTF8(tc))
|
255
|
+
rb_raise(rb_eArgError, "text must be utf8 encoded");
|
256
|
+
|
257
|
+
if (prbxs_dom->encodeEntities == 0)
|
258
|
+
xmlNodeSetContent(prbxs_domelement->node, tc);
|
259
|
+
else {
|
260
|
+
xmlChar *c;
|
261
|
+
c = xmlEncodeEntitiesReentrant(prbxs_domelement->node->doc,tc);
|
262
|
+
xmlNodeSetContent(prbxs_domelement->node, c);
|
263
|
+
xmlFree(c);
|
264
|
+
}
|
265
|
+
|
266
|
+
rbxs_dom_change_handlers_execute(prbxs_dom,RBXS_DOM_SIGNAL_CHANGE,rbxs_domtext_new(cSmartDomText, prbxs_domelement->doc, prbxs_domelement->node->children));
|
267
|
+
return(text);
|
268
|
+
}
|
269
|
+
|
270
|
+
/*
|
271
|
+
* Documentation
|
272
|
+
*/
|
273
|
+
VALUE rbxs_domelement_text_get(VALUE self)
|
274
|
+
{
|
275
|
+
rbxs_domelement *prbxs_domelement;
|
276
|
+
|
277
|
+
Data_Get_Struct(self, rbxs_domelement, prbxs_domelement);
|
278
|
+
if (prbxs_domelement->node->children != NULL)
|
279
|
+
if (prbxs_domelement->node->children->content != NULL)
|
280
|
+
return(rb_str_new2((char *)prbxs_domelement->node->children->content));
|
281
|
+
return(rb_str_new2(""));
|
282
|
+
}
|
283
|
+
|
284
|
+
/*
|
285
|
+
* Documentation
|
286
|
+
*/
|
287
|
+
VALUE rbxs_domelement_inspect(VALUE self)
|
288
|
+
{
|
289
|
+
VALUE *argv;
|
290
|
+
|
291
|
+
rbxs_domelement *prbxs_domelement;
|
292
|
+
Data_Get_Struct(self, rbxs_domelement, prbxs_domelement);
|
293
|
+
|
294
|
+
argv = ALLOCA_N(VALUE, 4);
|
295
|
+
argv[0] = rb_str_new2("#<%s:0x%x \"%s\">");
|
296
|
+
argv[1] = CLASS_OF(self);
|
297
|
+
argv[2] = rb_obj_id(self);
|
298
|
+
argv[3] = rb_str_new2((char *)prbxs_domelement->node->name);
|
299
|
+
return(rb_f_sprintf(4, argv));
|
300
|
+
}
|
301
|
+
|
302
|
+
/*
|
303
|
+
* Documentation
|
304
|
+
*/
|
305
|
+
VALUE rbxs_domelement_to_i(int argc, VALUE *argv, VALUE self)
|
306
|
+
{
|
307
|
+
VALUE b;
|
308
|
+
int base;
|
309
|
+
|
310
|
+
rb_scan_args(argc, argv, "01", &b);
|
311
|
+
if (argc == 0) base = 10;
|
312
|
+
else base = NUM2INT(b);
|
313
|
+
|
314
|
+
if (base < 0)
|
315
|
+
rb_raise(rb_eArgError, "illegal radix %d", base);
|
316
|
+
return(rb_str_to_inum(rbxs_domelement_text_get(self),base,Qfalse));
|
317
|
+
}
|
318
|
+
|
319
|
+
/*
|
320
|
+
* Documentation
|
321
|
+
*/
|
322
|
+
VALUE rbxs_domelement_to_f(VALUE self)
|
323
|
+
{
|
324
|
+
return rb_float_new(rb_str_to_dbl(rbxs_domelement_text_get(self), Qfalse));
|
325
|
+
}
|
326
|
+
|
327
|
+
/*
|
328
|
+
* Documentation
|
329
|
+
*/
|
330
|
+
VALUE rbxs_domelement_attributes(VALUE self)
|
331
|
+
{
|
332
|
+
return rbxs_domattributeset_new(cSmartDomAttributeSet,self);
|
333
|
+
}
|
334
|
+
|
335
|
+
static unsigned short checkArguments(int argc, VALUE *argv, VALUE *content, VALUE *attributes) {
|
336
|
+
if (argc < 1) rb_raise(rb_eArgError, "at least 1 argument is mandatory");
|
337
|
+
if (TYPE(argv[0]) == T_STRING) {
|
338
|
+
switch (argc) {
|
339
|
+
case 3:
|
340
|
+
if ((TYPE(argv[2]) == T_HASH) && (TYPE(argv[1]) != T_HASH)) {
|
341
|
+
*content = rb_obj_as_string(argv[1]);
|
342
|
+
*attributes = argv[2];
|
343
|
+
} else if ((TYPE(argv[1]) == T_HASH) && (TYPE(argv[2]) != T_HASH)) {
|
344
|
+
*content = rb_obj_as_string(argv[2]);
|
345
|
+
*attributes = argv[1];
|
346
|
+
} else
|
347
|
+
rb_raise(rb_eArgError, "argument 2 or 3 has to be a Hash");
|
348
|
+
break;
|
349
|
+
case 2:
|
350
|
+
if (TYPE(argv[1]) != T_HASH)
|
351
|
+
*content = rb_obj_as_string(argv[1]);
|
352
|
+
else if (TYPE(argv[1]) == T_HASH)
|
353
|
+
*attributes = argv[1];
|
354
|
+
else
|
355
|
+
rb_raise(rb_eArgError, "argument 2 has to be a String or a Hash");
|
356
|
+
break;
|
357
|
+
case 1:
|
358
|
+
break;
|
359
|
+
default:
|
360
|
+
rb_raise(rb_eArgError, "wrong number of arguments (needs 1 to 3)");
|
361
|
+
}
|
362
|
+
return(1);
|
363
|
+
} else if (rb_obj_is_kind_of(argv[0], cSmartDomElement) || rb_obj_is_kind_of(argv[0], cSmartDomNodeSet)) {
|
364
|
+
switch (argc) {
|
365
|
+
case 2:
|
366
|
+
if ((TYPE(argv[1]) != T_FIXNUM) || (NUM2INT(argv[1]) > 1) || (NUM2INT(argv[1]) < 0))
|
367
|
+
rb_raise(rb_eArgError, "argument 2 has to be a either ::MOVE or ::COPY");
|
368
|
+
break;
|
369
|
+
case 1:
|
370
|
+
break;
|
371
|
+
default:
|
372
|
+
rb_raise(rb_eArgError, "wrong number of arguments (needs 2)");
|
373
|
+
}
|
374
|
+
if (rb_obj_is_kind_of(argv[0], cSmartDomElement)) return(2);
|
375
|
+
if (rb_obj_is_kind_of(argv[0], cSmartDomNodeSet)) return(3);
|
376
|
+
} else {
|
377
|
+
rb_raise(rb_eArgError, "wrong type of first argument");
|
378
|
+
}
|
379
|
+
return 0;
|
380
|
+
}
|
381
|
+
|
382
|
+
static int addAttributes_each(VALUE key, VALUE value, xmlNodePtr arg) {
|
383
|
+
xmlAttrPtr attr;
|
384
|
+
unsigned char *tc;
|
385
|
+
VALUE str;
|
386
|
+
|
387
|
+
str = rb_obj_as_string(value);
|
388
|
+
if (NIL_P(str) || TYPE(str) != T_STRING)
|
389
|
+
rb_raise(rb_eTypeError, "cannot convert obj to string");
|
390
|
+
tc = (unsigned char *)StringValuePtr(str);
|
391
|
+
if (!xmlCheckUTF8(tc))
|
392
|
+
rb_raise(rb_eArgError, "text must be utf8 encoded");
|
393
|
+
|
394
|
+
str = rb_obj_as_string(key);
|
395
|
+
if (NIL_P(str) || TYPE(str) != T_STRING)
|
396
|
+
rb_raise(rb_eTypeError, "cannot convert obj to string");
|
397
|
+
attr = xmlNewProp(arg, (unsigned char *)StringValuePtr(str), tc);
|
398
|
+
|
399
|
+
if (attr == NULL)
|
400
|
+
rb_raise(rb_eRuntimeError, "Couldn't not add attribute");
|
401
|
+
return ST_CONTINUE;
|
402
|
+
}
|
403
|
+
|
404
|
+
static VALUE moveOrCopyElement(xmlNodePtr domelement, VALUE argA, VALUE argB, rbxs_domelement *prbxs_domelement, int where, int ret) {
|
405
|
+
xmlNodePtr new_domelement = NULL;
|
406
|
+
if ((argB == Qnil && domelement->doc == prbxs_domelement->node->doc) || (argB != Qnil && NUM2INT(argB) == 0)) {
|
407
|
+
if (domelement->doc == domelement->parent->doc && domelement->parent != NULL)
|
408
|
+
xmlUnlinkNode(domelement);
|
409
|
+
switch (where) {
|
410
|
+
case 1: new_domelement = xmlAddChild(prbxs_domelement->node,domelement); break;
|
411
|
+
case 2: new_domelement = xmlAddPrevSibling(prbxs_domelement->node,domelement); break;
|
412
|
+
case 3: new_domelement = xmlAddNextSibling(prbxs_domelement->node,domelement); break;
|
413
|
+
}
|
414
|
+
if (ret != 0)
|
415
|
+
return rbxs_domelement_new(cSmartDomElement,prbxs_domelement->doc,new_domelement);
|
416
|
+
} else if ((argB == Qnil && domelement->doc != prbxs_domelement->node->doc) || (argB != Qnil && NUM2INT(argB) == 1)) {
|
417
|
+
new_domelement = xmlCopyNode(domelement,1); // 1 == deep
|
418
|
+
switch (where) {
|
419
|
+
case 1: new_domelement = xmlAddChild(prbxs_domelement->node,new_domelement); break;
|
420
|
+
case 2: new_domelement = xmlAddPrevSibling(prbxs_domelement->node,new_domelement); break;
|
421
|
+
case 3: new_domelement = xmlAddNextSibling(prbxs_domelement->node,new_domelement); break;
|
422
|
+
}
|
423
|
+
if (ret != 0) return(rbxs_domelement_new(cSmartDomElement,prbxs_domelement->doc,new_domelement));
|
424
|
+
}
|
425
|
+
return(Qnil);
|
426
|
+
}
|
427
|
+
|
428
|
+
static VALUE rbxs_domelement_add_worker(int argc, VALUE *argv, VALUE self, int where) {
|
429
|
+
rbxs_domelement *prbxs_domelement, *prbxs_cdomelement;
|
430
|
+
rbxs_domnodeset *prbxs_cdomnodeset;
|
431
|
+
rbxs_dom *prbxs_dom;
|
432
|
+
xmlNodePtr new_domelement = NULL;
|
433
|
+
VALUE content;
|
434
|
+
VALUE attributes;
|
435
|
+
VALUE ret,str;
|
436
|
+
int i;
|
437
|
+
xmlChar *c = NULL;
|
438
|
+
|
439
|
+
content = Qnil;
|
440
|
+
attributes = rb_hash_new();
|
441
|
+
|
442
|
+
Data_Get_Struct(self, rbxs_domelement, prbxs_domelement);
|
443
|
+
|
444
|
+
switch (checkArguments(argc,argv,&content,&attributes)) {
|
445
|
+
case 1:
|
446
|
+
Data_Get_Struct(prbxs_domelement->doc, rbxs_dom, prbxs_dom);
|
447
|
+
if (content != Qnil) {
|
448
|
+
char *tc = StringValuePtr(content);
|
449
|
+
if (!xmlCheckUTF8((unsigned char *)tc))
|
450
|
+
rb_raise(rb_eArgError, "text must be utf8 encoded");
|
451
|
+
if (prbxs_dom->encodeEntities == 0)
|
452
|
+
c = xmlCharStrdup(tc);
|
453
|
+
else
|
454
|
+
c = xmlEncodeEntitiesReentrant(prbxs_domelement->node->doc,(unsigned char *)tc);
|
455
|
+
}
|
456
|
+
switch (where) {
|
457
|
+
case 1:
|
458
|
+
str = rb_obj_as_string(argv[0]);
|
459
|
+
if (NIL_P(str) || TYPE(str) != T_STRING)
|
460
|
+
rb_raise(rb_eTypeError, "cannot convert obj to string");
|
461
|
+
new_domelement = xmlNewChild(prbxs_domelement->node, NULL, (unsigned char *)StringValuePtr(str), c);
|
462
|
+
break;
|
463
|
+
case 2:
|
464
|
+
str = rb_obj_as_string(argv[0]);
|
465
|
+
if (NIL_P(str) || TYPE(str) != T_STRING)
|
466
|
+
rb_raise(rb_eTypeError, "cannot convert obj to string");
|
467
|
+
new_domelement = xmlNewDocNode(prbxs_domelement->node->doc, NULL, (unsigned char *)StringValuePtr(argv[0]), c);
|
468
|
+
new_domelement = xmlAddPrevSibling(prbxs_domelement->node,new_domelement);
|
469
|
+
break;
|
470
|
+
case 3:
|
471
|
+
str = rb_obj_as_string(argv[0]);
|
472
|
+
if (NIL_P(str) || TYPE(str) != T_STRING)
|
473
|
+
rb_raise(rb_eTypeError, "cannot convert obj to string");
|
474
|
+
new_domelement = xmlNewDocNode(prbxs_domelement->node->doc, NULL, (unsigned char *)StringValuePtr(argv[0]), c);
|
475
|
+
new_domelement = xmlAddNextSibling(prbxs_domelement->node,new_domelement);
|
476
|
+
break;
|
477
|
+
}
|
478
|
+
xmlFree(c);
|
479
|
+
if (new_domelement == NULL)
|
480
|
+
rb_raise(rb_eRuntimeError, "Couldn't add element");
|
481
|
+
if (!RHASH_EMPTY_P(attributes))
|
482
|
+
rb_hash_foreach(attributes, addAttributes_each, (st_data_t)new_domelement);
|
483
|
+
ret = rbxs_domelement_new(cSmartDomElement,prbxs_domelement->doc,new_domelement);
|
484
|
+
rbxs_dom_change_handlers_execute(prbxs_dom,RBXS_DOM_SIGNAL_ADD,ret);
|
485
|
+
return(ret);
|
486
|
+
break;
|
487
|
+
case 2:
|
488
|
+
Data_Get_Struct(argv[0], rbxs_domelement, prbxs_cdomelement);
|
489
|
+
ret = moveOrCopyElement(prbxs_cdomelement->node,argv[0],argc == 1 ? Qnil : argv[1],prbxs_domelement,where,1);
|
490
|
+
if (ret != Qnil) {
|
491
|
+
Data_Get_Struct(prbxs_domelement->doc, rbxs_dom, prbxs_dom);
|
492
|
+
rbxs_dom_change_handlers_execute(prbxs_dom,RBXS_DOM_SIGNAL_ADD,ret);
|
493
|
+
}
|
494
|
+
return(ret);
|
495
|
+
break;
|
496
|
+
case 3:
|
497
|
+
Data_Get_Struct(argv[0], rbxs_domnodeset, prbxs_cdomnodeset);
|
498
|
+
if (xmlXPathNodeSetIsEmpty(prbxs_cdomnodeset->nodeset)) return(Qnil);
|
499
|
+
for (i = 0; i < prbxs_cdomnodeset->nodeset->nodeNr; i++) {
|
500
|
+
if (prbxs_cdomnodeset->nodeset->nodeTab[i] == NULL) return (Qnil);
|
501
|
+
if (prbxs_cdomnodeset->nodeset->nodeTab[i]->type == XML_ELEMENT_NODE) {
|
502
|
+
Data_Get_Struct(prbxs_domelement->doc, rbxs_dom, prbxs_dom);
|
503
|
+
ret = moveOrCopyElement(prbxs_cdomnodeset->nodeset->nodeTab[i],argv[0],argc == 1 ? Qnil : argv[1],prbxs_domelement,where,0);
|
504
|
+
rbxs_dom_change_handlers_execute(prbxs_dom,RBXS_DOM_SIGNAL_ADD,ret);
|
505
|
+
}
|
506
|
+
}
|
507
|
+
return(argv[0]);
|
508
|
+
}
|
509
|
+
return(Qnil);
|
510
|
+
}
|
511
|
+
|
512
|
+
/*
|
513
|
+
* Documentation
|
514
|
+
*/
|
515
|
+
VALUE rbxs_domelement_add(int argc, VALUE *argv, VALUE self)
|
516
|
+
{
|
517
|
+
return(rbxs_domelement_add_worker(argc,argv,self,1));
|
518
|
+
}
|
519
|
+
/*
|
520
|
+
* Documentation
|
521
|
+
*/
|
522
|
+
VALUE rbxs_domelement_add_before(int argc, VALUE *argv, VALUE self)
|
523
|
+
{
|
524
|
+
return(rbxs_domelement_add_worker(argc,argv,self,2));
|
525
|
+
}
|
526
|
+
/*
|
527
|
+
* Documentation
|
528
|
+
*/
|
529
|
+
VALUE rbxs_domelement_add_after(int argc, VALUE *argv, VALUE self)
|
530
|
+
{
|
531
|
+
return(rbxs_domelement_add_worker(argc,argv,self,3));
|
532
|
+
}
|
533
|
+
|
534
|
+
/*
|
535
|
+
* Documentation
|
536
|
+
*/
|
537
|
+
VALUE rbxs_domelement_namespaces(VALUE self)
|
538
|
+
{
|
539
|
+
return rbxs_domnamespaceset_new(cSmartDomNamespaceSet,self);
|
540
|
+
}
|
541
|
+
|
542
|
+
/*
|
543
|
+
* Documentation
|
544
|
+
*/
|
545
|
+
VALUE rbxs_domelement_namespace(VALUE self)
|
546
|
+
{
|
547
|
+
rbxs_domelement *prbxs_domelement;
|
548
|
+
|
549
|
+
Data_Get_Struct(self, rbxs_domelement, prbxs_domelement);
|
550
|
+
if (prbxs_domelement->node->ns) {
|
551
|
+
return(rbxs_domnamespace_new(cSmartDomNamespace,self,prbxs_domelement->node->ns));
|
552
|
+
}
|
553
|
+
return(Qnil);
|
554
|
+
}
|
555
|
+
|
556
|
+
/*
|
557
|
+
* Documentation
|
558
|
+
*/
|
559
|
+
VALUE rbxs_domelement_namespace_q(VALUE self)
|
560
|
+
{
|
561
|
+
rbxs_domelement *prbxs_domelement;
|
562
|
+
|
563
|
+
Data_Get_Struct(self, rbxs_domelement, prbxs_domelement);
|
564
|
+
if (prbxs_domelement->node->ns)
|
565
|
+
return(Qtrue);
|
566
|
+
return(Qfalse);
|
567
|
+
}
|
568
|
+
|
569
|
+
/*
|
570
|
+
* Documentation
|
571
|
+
*/
|
572
|
+
VALUE rbxs_domelement_namespace_set(VALUE self,VALUE nsobj)
|
573
|
+
{
|
574
|
+
rbxs_domelement *prbxs_domelement;
|
575
|
+
rbxs_dom *prbxs_dom;
|
576
|
+
|
577
|
+
Data_Get_Struct(self, rbxs_domelement, prbxs_domelement);
|
578
|
+
Data_Get_Struct(prbxs_domelement->doc, rbxs_dom, prbxs_dom);
|
579
|
+
|
580
|
+
if (rb_obj_is_kind_of(nsobj,cSmartDomNamespace)) {
|
581
|
+
rbxs_domnamespace *prbxs_domnamespace;
|
582
|
+
Data_Get_Struct(nsobj, rbxs_domnamespace, prbxs_domnamespace);
|
583
|
+
xmlSetNs(prbxs_domelement->node,prbxs_domnamespace->ns);
|
584
|
+
rbxs_dom_change_handlers_execute(prbxs_dom,RBXS_DOM_SIGNAL_CHANGE,nsobj);
|
585
|
+
return(Qnil);
|
586
|
+
}
|
587
|
+
if (TYPE(nsobj) == T_STRING) {
|
588
|
+
xmlNsPtr ns;
|
589
|
+
ns = xmlSearchNs(prbxs_domelement->node->doc, prbxs_domelement->node, (unsigned char *)StringValuePtr(nsobj));
|
590
|
+
if (!ns) {
|
591
|
+
ns = xmlSearchNsByHref(prbxs_domelement->node->doc, prbxs_domelement->node, (unsigned char *)StringValuePtr(nsobj));
|
592
|
+
if (!ns) rb_raise(rb_eArgError, "String identifies no valid namespace");
|
593
|
+
}
|
594
|
+
xmlSetNs(prbxs_domelement->node,ns);
|
595
|
+
rbxs_dom_change_handlers_execute(prbxs_dom,RBXS_DOM_SIGNAL_CHANGE,rbxs_domnamespace_new(cSmartDomNamespace, prbxs_domelement->doc, ns));
|
596
|
+
return(Qnil);
|
597
|
+
}
|
598
|
+
rb_raise(rb_eArgError, "Expecting XML::Smart::Dom::Namespace");
|
599
|
+
}
|
600
|
+
|
601
|
+
// ***********************************************************************************
|
602
|
+
// Constructors
|
603
|
+
// ***********************************************************************************
|
604
|
+
VALUE rbxs_domelement_new(VALUE class, VALUE doc, xmlNodePtr node) {
|
605
|
+
rbxs_domelement *prbxs_domelement;
|
606
|
+
|
607
|
+
prbxs_domelement = (rbxs_domelement *)malloc(sizeof(rbxs_domelement));
|
608
|
+
if (prbxs_domelement == NULL )
|
609
|
+
rb_raise(rb_eNoMemError, "No memory left for XML::Smart::Dom::Element struct");
|
610
|
+
|
611
|
+
prbxs_domelement->doc = doc;
|
612
|
+
prbxs_domelement->node = node;
|
613
|
+
|
614
|
+
return(Data_Wrap_Struct(class, rbxs_domelement_mark, rbxs_domelement_free, prbxs_domelement));
|
615
|
+
}
|
616
|
+
|
617
|
+
// ***********************************************************************************
|
618
|
+
// Initialize class Node
|
619
|
+
// ***********************************************************************************
|
620
|
+
#ifdef RDOC__
|
621
|
+
mXML = rb_define_module( "XML" );
|
622
|
+
cSmart = rb_define_class_under( mXML, "Smart", rb_cObject );
|
623
|
+
cSmartDom = rb_define_class_under( cSmart, "Dom", rb_cObject );
|
624
|
+
#endif
|
625
|
+
|
626
|
+
void init_rbxs_domelement(void) {
|
627
|
+
cSmartDomElement = rb_define_class_under( cSmartDom, "Element", rb_cObject );
|
628
|
+
|
629
|
+
rb_define_const(cSmartDomElement, "MOVE", INT2NUM(0));
|
630
|
+
rb_define_const(cSmartDomElement, "COPY", INT2NUM(1));
|
631
|
+
|
632
|
+
rb_define_method(cSmartDomElement, "dump", rbxs_domelement_dump, 0);
|
633
|
+
rb_define_method(cSmartDomElement, "inspect", rbxs_domelement_inspect, 0);
|
634
|
+
rb_define_method(cSmartDomElement, "find", rbxs_domelement_find, -1);
|
635
|
+
rb_define_method(cSmartDomElement, "to_s", rbxs_domelement_text_get, 0);
|
636
|
+
rb_define_method(cSmartDomElement, "to_i", rbxs_domelement_to_i, -1);
|
637
|
+
rb_define_method(cSmartDomElement, "to_f", rbxs_domelement_to_f, 0);
|
638
|
+
rb_define_method(cSmartDomElement, "name", rbxs_domelement_name, 0);
|
639
|
+
rb_define_method(cSmartDomElement, "text", rbxs_domelement_text_get, 0);
|
640
|
+
rb_define_method(cSmartDomElement, "text=", rbxs_domelement_text_set, 1);
|
641
|
+
rb_define_method(cSmartDomElement, "children", rbxs_domelement_children, 0);
|
642
|
+
rb_define_method(cSmartDomElement, "children?", rbxs_domelement_children_q, 0);
|
643
|
+
rb_define_method(cSmartDomElement, "empty?", rbxs_domelement_children_empty_q, 0);
|
644
|
+
rb_define_method(cSmartDomElement, "mixed?", rbxs_domelement_children_mixed_q, 0);
|
645
|
+
rb_define_method(cSmartDomElement, "parent", rbxs_domelement_parent, 0);
|
646
|
+
rb_define_method(cSmartDomElement, "path", rbxs_domelement_path, 0);
|
647
|
+
rb_define_method(cSmartDomElement, "attributes", rbxs_domelement_attributes, 0);
|
648
|
+
rb_define_method(cSmartDomElement, "add", rbxs_domelement_add, -1);
|
649
|
+
rb_define_method(cSmartDomElement, "add_before", rbxs_domelement_add_before, -1);
|
650
|
+
rb_define_method(cSmartDomElement, "add_after", rbxs_domelement_add_after, -1);
|
651
|
+
rb_define_method(cSmartDomElement, "replace_by", rbxs_domelement_replace_by, 1);
|
652
|
+
rb_define_method(cSmartDomElement, "namespaces", rbxs_domelement_namespaces, 0);
|
653
|
+
rb_define_method(cSmartDomElement, "namespace", rbxs_domelement_namespace, 0);
|
654
|
+
rb_define_method(cSmartDomElement, "namespace?", rbxs_domelement_namespace_q, 0);
|
655
|
+
rb_define_method(cSmartDomElement, "namespace=", rbxs_domelement_namespace_set, 1);
|
656
|
+
}
|
data/rbxs_domelement.h
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
/* Please see the COPYING file for copyright and distribution information */
|
2
|
+
|
3
|
+
#ifndef __RBXS_DOMELEMENT_H__
|
4
|
+
#define __RBXS_DOMELEMENT_H__
|
5
|
+
|
6
|
+
#include "rbxs.h"
|
7
|
+
|
8
|
+
RUBY_EXTERN VALUE cSmartDomElement;
|
9
|
+
|
10
|
+
typedef struct rbxs_domelement {
|
11
|
+
VALUE doc;
|
12
|
+
xmlNodePtr node;
|
13
|
+
} rbxs_domelement;
|
14
|
+
|
15
|
+
RUBY_EXTERN VALUE rbxs_domelement_new(VALUE class, VALUE doc, xmlNodePtr node);
|
16
|
+
RUBY_EXTERN void init_rbxs_domelement(void);
|
17
|
+
|
18
|
+
#endif
|