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