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.
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