ruby-xml-smart 0.1.11-i486-linux

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.
Files changed (73) hide show
  1. data/AUTHORS +4 -0
  2. data/COPYING +504 -0
  3. data/Changelog +192 -0
  4. data/README +52 -0
  5. data/Rakefile +112 -0
  6. data/TODO +6 -0
  7. data/examples/EXAMPLE.xml +17 -0
  8. data/examples/EXAMPLE.xml.sic +17 -0
  9. data/examples/Visualise/EXAMPLE.xml +18 -0
  10. data/examples/Visualise/term-ansicolor-0.0.4/CHANGES +11 -0
  11. data/examples/Visualise/term-ansicolor-0.0.4/GPL +340 -0
  12. data/examples/Visualise/term-ansicolor-0.0.4/README.en +23 -0
  13. data/examples/Visualise/term-ansicolor-0.0.4/Rakefile +72 -0
  14. data/examples/Visualise/term-ansicolor-0.0.4/VERSION +1 -0
  15. data/examples/Visualise/term-ansicolor-0.0.4/examples/cdiff.rb +20 -0
  16. data/examples/Visualise/term-ansicolor-0.0.4/examples/example.rb +82 -0
  17. data/examples/Visualise/term-ansicolor-0.0.4/install.rb +12 -0
  18. data/examples/Visualise/term-ansicolor-0.0.4/lib/term/ansicolor.rb +78 -0
  19. data/examples/Visualise/xpath_visual.rb +45 -0
  20. data/examples/add_children.rb +14 -0
  21. data/examples/add_elements.rb +13 -0
  22. data/examples/attrs.rb +15 -0
  23. data/examples/children.rb +14 -0
  24. data/examples/concurrent.rb +30 -0
  25. data/examples/copy.rb +23 -0
  26. data/examples/create.rb +18 -0
  27. data/examples/delete.rb +30 -0
  28. data/examples/move_elements.rb +12 -0
  29. data/examples/namespace.rb +14 -0
  30. data/examples/namespace_detailed.rb +36 -0
  31. data/examples/namespace_find.rb +20 -0
  32. data/examples/pull.rb +18 -0
  33. data/examples/qname.rb +16 -0
  34. data/examples/replace.rb +14 -0
  35. data/examples/set_OR_replace.rb +32 -0
  36. data/examples/signals.rb +28 -0
  37. data/examples/string.rb +27 -0
  38. data/examples/write.rb +11 -0
  39. data/examples/xpath_attrs.rb +19 -0
  40. data/examples/xpath_functions.rb +7 -0
  41. data/examples/xpath_root.rb +6 -0
  42. data/extconf.rb +29 -0
  43. data/rbxs.c +136 -0
  44. data/rbxs.h +53 -0
  45. data/rbxs_dom.c +483 -0
  46. data/rbxs_dom.h +32 -0
  47. data/rbxs_domattribute.c +189 -0
  48. data/rbxs_domattribute.h +18 -0
  49. data/rbxs_domattributeset.c +182 -0
  50. data/rbxs_domattributeset.h +17 -0
  51. data/rbxs_domelement.c +656 -0
  52. data/rbxs_domelement.h +18 -0
  53. data/rbxs_domnamespace.c +127 -0
  54. data/rbxs_domnamespace.h +18 -0
  55. data/rbxs_domnamespaceset.c +276 -0
  56. data/rbxs_domnamespaceset.h +17 -0
  57. data/rbxs_domnodeset.c +284 -0
  58. data/rbxs_domnodeset.h +19 -0
  59. data/rbxs_domother.c +121 -0
  60. data/rbxs_domother.h +18 -0
  61. data/rbxs_domtext.c +165 -0
  62. data/rbxs_domtext.h +18 -0
  63. data/rbxs_pull.c +244 -0
  64. data/rbxs_pull.h +17 -0
  65. data/rbxs_pullattribute.c +124 -0
  66. data/rbxs_pullattribute.h +18 -0
  67. data/rbxs_pullattributeset.c +156 -0
  68. data/rbxs_pullattributeset.h +17 -0
  69. data/rbxs_qname.c +267 -0
  70. data/rbxs_qname.h +18 -0
  71. data/rbxs_utils.h +39 -0
  72. data/test/namespace_test.rb +83 -0
  73. 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