libxml-ruby 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/CHANGES +22 -0
  2. data/README +3 -1
  3. data/ext/libxml/cbg.c +86 -76
  4. data/ext/libxml/extconf.rb +2 -1
  5. data/ext/libxml/libxml.c +899 -885
  6. data/ext/libxml/ruby_libxml.h +65 -70
  7. data/ext/libxml/ruby_xml_attr.c +485 -500
  8. data/ext/libxml/ruby_xml_attributes.c +107 -106
  9. data/ext/libxml/ruby_xml_document.c +355 -356
  10. data/ext/libxml/ruby_xml_dtd.c +119 -117
  11. data/ext/libxml/ruby_xml_error.c +1112 -581
  12. data/ext/libxml/ruby_xml_html_parser.c +35 -34
  13. data/ext/libxml/ruby_xml_input.c +182 -187
  14. data/ext/libxml/ruby_xml_input_cbg.c +197 -179
  15. data/ext/libxml/ruby_xml_node.c +1529 -1566
  16. data/ext/libxml/ruby_xml_node.h +2 -2
  17. data/ext/libxml/ruby_xml_ns.c +150 -156
  18. data/ext/libxml/ruby_xml_parser.c +37 -36
  19. data/ext/libxml/ruby_xml_parser_context.c +657 -659
  20. data/ext/libxml/ruby_xml_reader.c +203 -209
  21. data/ext/libxml/ruby_xml_relaxng.c +29 -25
  22. data/ext/libxml/ruby_xml_sax_parser.c +33 -32
  23. data/ext/libxml/ruby_xml_schema.c +165 -161
  24. data/ext/libxml/ruby_xml_state.c +19 -21
  25. data/ext/libxml/ruby_xml_xinclude.c +24 -25
  26. data/ext/libxml/ruby_xml_xpath.c +108 -108
  27. data/ext/libxml/ruby_xml_xpath_context.c +305 -293
  28. data/ext/libxml/ruby_xml_xpath_expression.c +24 -24
  29. data/ext/libxml/ruby_xml_xpath_object.c +89 -96
  30. data/ext/libxml/ruby_xml_xpointer.c +107 -109
  31. data/ext/libxml/ruby_xml_xpointer.h +13 -13
  32. data/ext/libxml/version.h +2 -2
  33. data/ext/mingw/Rakefile +1 -1
  34. data/ext/vc/libxml_ruby.vcproj +1 -1
  35. data/lib/libxml/error.rb +4 -4
  36. data/test/tc_node_edit.rb +14 -2
  37. data/test/tc_node_text.rb +9 -9
  38. metadata +2 -2
@@ -1,70 +1,65 @@
1
- /* Please see the LICENSE file for copyright and distribution information */
2
-
3
- #ifndef __RUBY_LIBXML_H__
4
- #define __RUBY_LIBXML_H__
5
-
6
- #include "version.h"
7
-
8
- #include <ruby.h>
9
- #include <rubyio.h>
10
- #include <util.h>
11
- #include <libxml/parser.h>
12
- #include <libxml/parserInternals.h>
13
- #include <libxml/debugXML.h>
14
- #include <libxml/xmlversion.h>
15
- #include <libxml/xmlmemory.h>
16
- #include <libxml/xpath.h>
17
- #include <libxml/valid.h>
18
- #include <libxml/catalog.h>
19
- #include <libxml/HTMLparser.h>
20
- #include <libxml/xmlreader.h>
21
-
22
- // Maybe not yet defined in ruby
23
- #ifndef RSTRING_LEN
24
- #define RSTRING_LEN(x) RSTRING(x)->len
25
- #endif
26
-
27
- // not in Ruby 1.9
28
- #ifndef GetWriteFile
29
- #define GetWriteFile(fp) rb_io_stdio_file(fp)
30
- #define OpenFile rb_io_t
31
- #endif
32
-
33
- #ifdef LIBXML_DEBUG_ENABLED
34
- #include <libxml/xpathInternals.h>
35
- #endif
36
- #ifdef LIBXML_XINCLUDE_ENABLED
37
- #include <libxml/xinclude.h>
38
- #endif
39
- #ifdef LIBXML_XPTR_ENABLED
40
- #include <libxml/xpointer.h>
41
- #endif
42
-
43
- #include "ruby_xml_error.h"
44
- #include "ruby_xml_input.h"
45
- #include "ruby_xml_state.h"
46
- #include "ruby_xml_attributes.h"
47
- #include "ruby_xml_attr.h"
48
- #include "ruby_xml_document.h"
49
- #include "ruby_xml_node.h"
50
- #include "ruby_xml_ns.h"
51
- #include "ruby_xml_parser.h"
52
- #include "ruby_xml_parser_context.h"
53
- #include "ruby_xml_sax_parser.h"
54
- #include "ruby_xml_xinclude.h"
55
- #include "ruby_xml_xpath.h"
56
- #include "ruby_xml_xpath_expression.h"
57
- #include "ruby_xml_xpath_context.h"
58
- #include "ruby_xml_xpath_object.h"
59
- #include "ruby_xml_xpointer.h"
60
- #include "ruby_xml_input_cbg.h"
61
- #include "ruby_xml_dtd.h"
62
- #include "ruby_xml_schema.h"
63
- #include "ruby_xml_relaxng.h"
64
- #include "ruby_xml_html_parser.h"
65
- #include "ruby_xml_reader.h"
66
-
67
- extern VALUE mLibXML;
68
- extern VALUE mXML;
69
-
70
- #endif
1
+ /* Please see the LICENSE file for copyright and distribution information */
2
+
3
+ #ifndef __RUBY_LIBXML_H__
4
+ #define __RUBY_LIBXML_H__
5
+
6
+ #include "version.h"
7
+
8
+ #include <ruby.h>
9
+ #include <rubyio.h>
10
+ #include <util.h>
11
+ #include <libxml/parser.h>
12
+ #include <libxml/parserInternals.h>
13
+ #include <libxml/debugXML.h>
14
+ #include <libxml/xmlversion.h>
15
+ #include <libxml/xmlmemory.h>
16
+ #include <libxml/xpath.h>
17
+ #include <libxml/valid.h>
18
+ #include <libxml/catalog.h>
19
+ #include <libxml/HTMLparser.h>
20
+ #include <libxml/xmlreader.h>
21
+
22
+ // not in Ruby 1.9
23
+ #ifndef GetWriteFile
24
+ #define GetWriteFile(fp) rb_io_stdio_file(fp)
25
+ #define OpenFile rb_io_t
26
+ #endif
27
+
28
+ #ifdef LIBXML_DEBUG_ENABLED
29
+ #include <libxml/xpathInternals.h>
30
+ #endif
31
+ #ifdef LIBXML_XINCLUDE_ENABLED
32
+ #include <libxml/xinclude.h>
33
+ #endif
34
+ #ifdef LIBXML_XPTR_ENABLED
35
+ #include <libxml/xpointer.h>
36
+ #endif
37
+
38
+ #include "ruby_xml_error.h"
39
+ #include "ruby_xml_input.h"
40
+ #include "ruby_xml_state.h"
41
+ #include "ruby_xml_attributes.h"
42
+ #include "ruby_xml_attr.h"
43
+ #include "ruby_xml_document.h"
44
+ #include "ruby_xml_node.h"
45
+ #include "ruby_xml_ns.h"
46
+ #include "ruby_xml_parser.h"
47
+ #include "ruby_xml_parser_context.h"
48
+ #include "ruby_xml_sax_parser.h"
49
+ #include "ruby_xml_xinclude.h"
50
+ #include "ruby_xml_xpath.h"
51
+ #include "ruby_xml_xpath_expression.h"
52
+ #include "ruby_xml_xpath_context.h"
53
+ #include "ruby_xml_xpath_object.h"
54
+ #include "ruby_xml_xpointer.h"
55
+ #include "ruby_xml_input_cbg.h"
56
+ #include "ruby_xml_dtd.h"
57
+ #include "ruby_xml_schema.h"
58
+ #include "ruby_xml_relaxng.h"
59
+ #include "ruby_xml_html_parser.h"
60
+ #include "ruby_xml_reader.h"
61
+
62
+ extern VALUE mLibXML;
63
+ extern VALUE mXML;
64
+
65
+ #endif
@@ -1,500 +1,485 @@
1
- /* $Id: ruby_xml_attr.c 612 2008-11-21 08:01:29Z cfis $ */
2
-
3
- /* Please see the LICENSE file for copyright and distribution information */
4
-
5
- /*
6
- * Document-class: LibXML::XML::Attr
7
- *
8
- * Provides access to an single element attribute.
9
- *
10
- * Basic Usage:
11
- *
12
- * require 'xml'
13
- *
14
- * doc = XML::Document.new(<some_file>)
15
- * attribute = doc.root.attributes.get_attribute_ns('http://www.w3.org/1999/xlink', 'href')
16
- * attribute.name == 'href'
17
- * attribute.value == 'http://www.mydocument.com'
18
- * attribute.remove!
19
- */
20
-
21
- #include "ruby_libxml.h"
22
- #include "ruby_xml_attr.h"
23
-
24
- VALUE cXMLAttr;
25
-
26
- void rxml_attr_free(xmlAttrPtr xattr) {
27
- if (!xattr) return;
28
-
29
- if (xattr != NULL ) {
30
- xattr->_private=NULL;
31
- if (xattr->parent == NULL && xattr->doc == NULL ) {
32
- #ifdef NODE_DEBUG
33
- fprintf(stderr,"ruby_xfree rxn=0x%x xn=0x%x o=0x%x\n",(long)rxn,(long)rxn->node,(long)rxn->node->_private);
34
- #endif
35
- xmlFreeProp(xattr);
36
- }
37
-
38
- xattr=NULL;
39
- }
40
- }
41
-
42
- void
43
- rxml_attr_mark(xmlAttrPtr xattr) {
44
- if (xattr == NULL) return;
45
-
46
- if (xattr->_private == NULL ) {
47
- rb_warning("XmlAttr is not bound! (%s:%d)",
48
- __FILE__,__LINE__);
49
- return;
50
- }
51
-
52
- rxml_node_mark_common((xmlNodePtr)xattr);
53
- }
54
-
55
- VALUE
56
- rxml_attr_wrap(xmlAttrPtr xattr)
57
- {
58
- VALUE result;
59
- // This node is already wrapped
60
- if (xattr->_private != NULL)
61
- return (VALUE)xattr->_private;
62
-
63
- result = Data_Wrap_Struct(cXMLAttr,
64
- rxml_attr_mark, rxml_attr_free,
65
- xattr);
66
-
67
- xattr->_private=(void*)result;
68
- #ifdef NODE_DEBUG
69
- fprintf(stderr,"wrap rxn=0x%x xn=0x%x o=0x%x\n",(long)rxn,(long)xnode,(long)obj);
70
- #endif
71
- return result;
72
- }
73
-
74
-
75
- static VALUE
76
- rxml_attr_alloc(VALUE klass)
77
- {
78
- return Data_Wrap_Struct(cXMLAttr,
79
- rxml_attr_mark, rxml_attr_free,
80
- NULL);
81
- }
82
-
83
- /*
84
- * call-seq:
85
- * attr.initialize(node, "name", "value")
86
- *
87
- * Creates a new attribute for the node.
88
- *
89
- * node: The XML::Node that will contain the attribute
90
- * name: The name of the attribute
91
- * value: The value of the attribute
92
- *
93
- * attr = XML::Attr.new(doc.root, 'name', 'libxml')
94
- */
95
- static VALUE
96
- rxml_attr_initialize(int argc, VALUE *argv, VALUE self) {
97
- VALUE node = argv[0];
98
- VALUE name = argv[1];
99
- VALUE value = argv[2];
100
- VALUE ns = (argc == 4 ? argv[3] : Qnil);
101
-
102
- xmlNodePtr xnode;
103
- xmlAttrPtr xattr;
104
-
105
- if ( argc < 3 || argc > 4 )
106
- rb_raise(rb_eArgError, "Wrong number of arguments (3 or 4)");
107
-
108
- Check_Type(name, T_STRING);
109
- Check_Type(value, T_STRING);
110
-
111
- Data_Get_Struct(node, xmlNode, xnode);
112
-
113
- if (xnode->type != XML_ELEMENT_NODE)
114
- rb_raise(rb_eArgError, "Attributes can only be created on element nodes.");
115
-
116
- if NIL_P(ns)
117
- {
118
- xattr = xmlNewProp(xnode, (xmlChar*)StringValuePtr(name), (xmlChar*)StringValuePtr(value));
119
- }
120
- else
121
- {
122
- xmlNsPtr xns;
123
- Data_Get_Struct(ns, xmlNs, xns);
124
- xattr = xmlNewNsProp(xnode, xns, (xmlChar*)StringValuePtr(name), (xmlChar*)StringValuePtr(value));
125
- }
126
-
127
- if (!xattr)
128
- rb_raise(rb_eRuntimeError, "Could not create attribute.");
129
-
130
- xattr->_private = (void *)self;
131
- DATA_PTR(self) = xattr;
132
- return self;
133
- }
134
-
135
- /*
136
- * call-seq:
137
- * attr.child -> node
138
- *
139
- * Obtain this attribute's child attribute(s).
140
- */
141
- static VALUE
142
- rxml_attr_child_get(VALUE self) {
143
- xmlAttrPtr xattr;
144
- Data_Get_Struct(self, xmlAttr, xattr);
145
- if (xattr->children == NULL)
146
- return(Qnil);
147
- else
148
- return(rxml_node2_wrap(cXMLNode, (xmlNodePtr)xattr->children));
149
- }
150
-
151
-
152
- /*
153
- * call-seq:
154
- * attr.child? -> (true|false)
155
- *
156
- * Returns whether this attribute has child attributes.
157
- */
158
- static VALUE
159
- rxml_attr_child_q(VALUE self) {
160
- xmlAttrPtr xattr;
161
- Data_Get_Struct(self, xmlAttr, xattr);
162
- if (xattr->children == NULL)
163
- return(Qfalse);
164
- else
165
- return(Qtrue);
166
- }
167
-
168
-
169
- /*
170
- * call-seq:
171
- * attr.doc -> XML::Document
172
- *
173
- * Returns this attribute's document.
174
- *
175
- * doc.root.attributes.get_attribute('name').doc == doc
176
- */
177
- static VALUE
178
- rxml_attr_doc_get(VALUE self) {
179
- xmlAttrPtr xattr;
180
- Data_Get_Struct(self, xmlAttr, xattr);
181
- if (xattr->doc == NULL)
182
- return(Qnil);
183
- else
184
- return(rxml_document_wrap(xattr->doc));
185
- }
186
-
187
- /*
188
- * call-seq:
189
- * attr.doc? -> (true|false)
190
- *
191
- * Determine whether this attribute is associated with an
192
- * XML::Document.
193
- */
194
- static VALUE
195
- rxml_attr_doc_q(VALUE self) {
196
- xmlAttrPtr xattr;
197
- Data_Get_Struct(self, xmlAttr, xattr);
198
- if (xattr->doc == NULL)
199
- return(Qfalse);
200
- else
201
- return(Qtrue);
202
- }
203
-
204
-
205
- /*
206
- * call-seq:
207
- * attr.last -> node
208
- *
209
- * Obtain the last attribute.
210
- */
211
- static VALUE
212
- rxml_attr_last_get(VALUE self) {
213
- xmlAttrPtr xattr;
214
- Data_Get_Struct(self, xmlAttr, xattr);
215
- if (xattr->last == NULL)
216
- return(Qnil);
217
- else
218
- return(rxml_node2_wrap(cXMLNode, xattr->last));
219
- }
220
-
221
-
222
- /*
223
- * call-seq:
224
- * attr.last? -> (true|false)
225
- *
226
- * Determine whether this is the last attribute.
227
- */
228
- static VALUE
229
- rxml_attr_last_q(VALUE self) {
230
- xmlAttrPtr xattr;
231
- Data_Get_Struct(self, xmlAttr, xattr);
232
- if (xattr->last == NULL)
233
- return(Qfalse);
234
- else
235
- return(Qtrue);
236
- }
237
-
238
- /*
239
- * call-seq:
240
- * attr.name -> "name"
241
- *
242
- * Obtain this attribute's name.
243
- */
244
- static VALUE
245
- rxml_attr_name_get(VALUE self) {
246
- xmlAttrPtr xattr;
247
- Data_Get_Struct(self, xmlAttr, xattr);
248
-
249
- if (xattr->name == NULL)
250
- return(Qnil);
251
- else
252
- return(rb_str_new2((const char*)xattr->name));
253
- }
254
-
255
- /*
256
- * call-seq:
257
- * attr.next -> node
258
- *
259
- * Obtain the next attribute.
260
- */
261
- static VALUE
262
- rxml_attr_next_get(VALUE self) {
263
- xmlAttrPtr xattr;
264
- Data_Get_Struct(self, xmlAttr, xattr);
265
- if (xattr->next == NULL)
266
- return(Qnil);
267
- else
268
- return(rxml_attr_wrap(xattr->next));
269
- }
270
-
271
-
272
- /*
273
- * call-seq:
274
- * attr.next? -> (true|false)
275
- *
276
- * Determine whether there is a next attribute.
277
- */
278
- static VALUE
279
- rxml_attr_next_q(VALUE self) {
280
- xmlAttrPtr xattr;
281
- Data_Get_Struct(self, xmlAttr, xattr);
282
- if (xattr->next == NULL)
283
- return(Qfalse);
284
- else
285
- return(Qtrue);
286
- }
287
-
288
-
289
- /*
290
- * call-seq:
291
- * attr.type_name -> "attribute"
292
- *
293
- * Obtain this attribute node's type name.
294
- */
295
- static VALUE
296
- rxml_attr_node_type_name(VALUE self) {
297
- return(rb_str_new2("attribute"));
298
- }
299
-
300
-
301
- /*
302
- * call-seq:
303
- * attr.ns -> namespace
304
- *
305
- * Obtain this attribute's associated XML::NS, if any.
306
- */
307
- static VALUE
308
- rxml_attr_ns_get(VALUE self) {
309
- xmlAttrPtr xattr;
310
- Data_Get_Struct(self, xmlAttr, xattr);
311
- if (xattr->ns == NULL)
312
- return(Qnil);
313
- else
314
- return(rxml_ns_wrap(xattr->ns));
315
- }
316
-
317
-
318
- /*
319
- * call-seq:
320
- * attr.ns? -> (true|false)
321
- *
322
- * Determine whether this attribute has an associated
323
- * namespace.
324
- */
325
- static VALUE
326
- rxml_attr_ns_q(VALUE self) {
327
- xmlAttrPtr xattr;
328
- Data_Get_Struct(self, xmlAttr, xattr);
329
- if (xattr->ns == NULL)
330
- return(Qfalse);
331
- else
332
- return(Qtrue);
333
- }
334
-
335
-
336
- /*
337
- * call-seq:
338
- * attr.parent -> node
339
- *
340
- * Obtain this attribute node's parent.
341
- */
342
- static VALUE
343
- rxml_attr_parent_get(VALUE self) {
344
- xmlAttrPtr xattr;
345
- Data_Get_Struct(self, xmlAttr, xattr);
346
- if (xattr->parent == NULL)
347
- return(Qnil);
348
- else
349
- return(rxml_node2_wrap(cXMLNode, xattr->parent));
350
- }
351
-
352
-
353
- /*
354
- * call-seq:
355
- * attr.parent? -> (true|false)
356
- *
357
- * Determine whether this attribute has a parent.
358
- */
359
- static VALUE
360
- rxml_attr_parent_q(VALUE self) {
361
- xmlAttrPtr xattr;
362
- Data_Get_Struct(self, xmlAttr, xattr);
363
- if (xattr->parent == NULL)
364
- return(Qfalse);
365
- else
366
- return(Qtrue);
367
- }
368
-
369
-
370
- /*
371
- * call-seq:
372
- * attr.prev -> node
373
- *
374
- * Obtain the previous attribute.
375
- */
376
- static VALUE
377
- rxml_attr_prev_get(VALUE self) {
378
- xmlAttrPtr xattr;
379
- Data_Get_Struct(self, xmlAttr, xattr);
380
- if (xattr->prev == NULL)
381
- return(Qnil);
382
- else
383
- return(rxml_attr_wrap(xattr->prev));
384
- }
385
-
386
-
387
- /*
388
- * call-seq:
389
- * attr.prev? -> (true|false)
390
- *
391
- * Determine whether there is a previous attribute.
392
- */
393
- static VALUE
394
- rxml_attr_prev_q(VALUE self) {
395
- xmlAttrPtr xattr;
396
- Data_Get_Struct(self, xmlAttr, xattr);
397
- if (xattr->prev == NULL)
398
- return(Qfalse);
399
- else
400
- return(Qtrue);
401
- }
402
-
403
-
404
- /*
405
- * call-seq:
406
- * node.remove! -> nil
407
- *
408
- * Removes this attribute from it's parent.
409
- */
410
- static VALUE
411
- rxml_attr_remove_ex(VALUE self) {
412
- xmlAttrPtr xattr;
413
- Data_Get_Struct(self, xmlAttr, xattr);
414
-
415
- if (xattr->_private == NULL)
416
- xmlRemoveProp(xattr);
417
- else
418
- xmlUnlinkNode((xmlNodePtr)xattr);
419
-
420
- return(Qnil);
421
- }
422
-
423
- /*
424
- * call-seq:
425
- * attr.value -> "value"
426
- *
427
- * Obtain the value of this attribute.
428
- */
429
- VALUE
430
- rxml_attr_value_get(VALUE self) {
431
- xmlAttrPtr xattr;
432
- xmlChar *value;
433
- VALUE result = Qnil;
434
-
435
- Data_Get_Struct(self, xmlAttr, xattr);
436
- if (rxml_attr_parent_q(self) == Qtrue) {
437
- value = xmlGetProp(xattr->parent, xattr->name);
438
- if (value != NULL)
439
- {
440
- result = rb_str_new2((const char*)value);
441
- xmlFree(value);
442
- }
443
- }
444
- return(result);
445
- }
446
-
447
-
448
- /*
449
- * call-seq:
450
- * attr.value = "value"
451
- *
452
- * Sets the value of this attribute.
453
- */
454
- VALUE
455
- rxml_attr_value_set(VALUE self, VALUE val) {
456
- xmlAttrPtr xattr;
457
-
458
- Check_Type(val, T_STRING);
459
- Data_Get_Struct(self, xmlAttr, xattr);
460
-
461
- if (xattr->ns)
462
- xmlSetNsProp(xattr->parent, xattr->ns, xattr->name, (xmlChar*)StringValuePtr(val));
463
- else
464
- xmlSetProp(xattr->parent, xattr->name, (xmlChar*)StringValuePtr(val));
465
-
466
- return(self);
467
- }
468
-
469
-
470
- // Rdoc needs to know
471
- #ifdef RDOC_NEVER_DEFINED
472
- mLibXML = rb_define_module("LibXML");
473
- mXML = rb_define_module_under(mLibXML, "XML");
474
- #endif
475
-
476
- void
477
- ruby_init_xml_attr(void) {
478
- cXMLAttr = rb_define_class_under(mXML, "Attr", rb_cObject);
479
- rb_define_alloc_func(cXMLAttr, rxml_attr_alloc);
480
- rb_define_method(cXMLAttr, "initialize", rxml_attr_initialize, -1);
481
- rb_define_method(cXMLAttr, "child", rxml_attr_child_get, 0);
482
- rb_define_method(cXMLAttr, "child?", rxml_attr_child_q, 0);
483
- rb_define_method(cXMLAttr, "doc", rxml_attr_doc_get, 0);
484
- rb_define_method(cXMLAttr, "doc?", rxml_attr_doc_q, 0);
485
- rb_define_method(cXMLAttr, "last", rxml_attr_last_get, 0);
486
- rb_define_method(cXMLAttr, "last?", rxml_attr_last_q, 0);
487
- rb_define_method(cXMLAttr, "name", rxml_attr_name_get, 0);
488
- rb_define_method(cXMLAttr, "next", rxml_attr_next_get, 0);
489
- rb_define_method(cXMLAttr, "next?", rxml_attr_next_q, 0);
490
- rb_define_method(cXMLAttr, "node_type_name", rxml_attr_node_type_name, 0);
491
- rb_define_method(cXMLAttr, "ns", rxml_attr_ns_get, 0);
492
- rb_define_method(cXMLAttr, "ns?", rxml_attr_ns_q, 0);
493
- rb_define_method(cXMLAttr, "parent", rxml_attr_parent_get, 0);
494
- rb_define_method(cXMLAttr, "parent?", rxml_attr_parent_q, 0);
495
- rb_define_method(cXMLAttr, "prev", rxml_attr_prev_get, 0);
496
- rb_define_method(cXMLAttr, "prev?", rxml_attr_prev_q, 0);
497
- rb_define_method(cXMLAttr, "remove!", rxml_attr_remove_ex, 0);
498
- rb_define_method(cXMLAttr, "value", rxml_attr_value_get, 0);
499
- rb_define_method(cXMLAttr, "value=", rxml_attr_value_set, 1);
500
- }
1
+ /* $Id: ruby_xml_attr.c 650 2008-11-30 03:40:22Z cfis $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ /*
6
+ * Document-class: LibXML::XML::Attr
7
+ *
8
+ * Provides access to an single element attribute.
9
+ *
10
+ * Basic Usage:
11
+ *
12
+ * require 'xml'
13
+ *
14
+ * doc = XML::Document.new(<some_file>)
15
+ * attribute = doc.root.attributes.get_attribute_ns('http://www.w3.org/1999/xlink', 'href')
16
+ * attribute.name == 'href'
17
+ * attribute.value == 'http://www.mydocument.com'
18
+ * attribute.remove!
19
+ */
20
+
21
+ #include "ruby_libxml.h"
22
+ #include "ruby_xml_attr.h"
23
+
24
+ VALUE cXMLAttr;
25
+
26
+ void rxml_attr_free(xmlAttrPtr xattr)
27
+ {
28
+ if (!xattr)
29
+ return;
30
+
31
+ if (xattr != NULL)
32
+ {
33
+ xattr->_private = NULL;
34
+ if (xattr->parent == NULL && xattr->doc == NULL)
35
+ {
36
+ #ifdef NODE_DEBUG
37
+ fprintf(stderr,"ruby_xfree rxn=0x%x xn=0x%x o=0x%x\n",(long)rxn,(long)rxn->node,(long)rxn->node->_private);
38
+ #endif
39
+ xmlFreeProp(xattr);
40
+ }
41
+
42
+ xattr = NULL;
43
+ }
44
+ }
45
+
46
+ void rxml_attr_mark(xmlAttrPtr xattr)
47
+ {
48
+ if (xattr == NULL)
49
+ return;
50
+
51
+ if (xattr->_private == NULL)
52
+ {
53
+ rb_warning("XmlAttr is not bound! (%s:%d)", __FILE__, __LINE__);
54
+ return;
55
+ }
56
+
57
+ rxml_node_mark_common((xmlNodePtr) xattr);
58
+ }
59
+
60
+ VALUE rxml_attr_wrap(xmlAttrPtr xattr)
61
+ {
62
+ VALUE result;
63
+ // This node is already wrapped
64
+ if (xattr->_private != NULL)
65
+ return (VALUE) xattr->_private;
66
+
67
+ result = Data_Wrap_Struct(cXMLAttr, rxml_attr_mark, rxml_attr_free, xattr);
68
+
69
+ xattr->_private = (void*) result;
70
+ #ifdef NODE_DEBUG
71
+ fprintf(stderr,"wrap rxn=0x%x xn=0x%x o=0x%x\n",(long)rxn,(long)xnode,(long)obj);
72
+ #endif
73
+ return result;
74
+ }
75
+
76
+ static VALUE rxml_attr_alloc(VALUE klass)
77
+ {
78
+ return Data_Wrap_Struct(klass, rxml_attr_mark, rxml_attr_free, NULL);
79
+ }
80
+
81
+ /*
82
+ * call-seq:
83
+ * attr.initialize(node, "name", "value")
84
+ *
85
+ * Creates a new attribute for the node.
86
+ *
87
+ * node: The XML::Node that will contain the attribute
88
+ * name: The name of the attribute
89
+ * value: The value of the attribute
90
+ *
91
+ * attr = XML::Attr.new(doc.root, 'name', 'libxml')
92
+ */
93
+ static VALUE rxml_attr_initialize(int argc, VALUE *argv, VALUE self)
94
+ {
95
+ VALUE node = argv[0];
96
+ VALUE name = argv[1];
97
+ VALUE value = argv[2];
98
+ VALUE ns = (argc == 4 ? argv[3] : Qnil);
99
+
100
+ xmlNodePtr xnode;
101
+ xmlAttrPtr xattr;
102
+
103
+ if (argc < 3 || argc > 4)
104
+ rb_raise(rb_eArgError, "Wrong number of arguments (3 or 4)");
105
+
106
+ Check_Type(name, T_STRING);
107
+ Check_Type(value, T_STRING);
108
+
109
+ Data_Get_Struct(node, xmlNode, xnode);
110
+
111
+ if (xnode->type != XML_ELEMENT_NODE)
112
+ rb_raise(rb_eArgError, "Attributes can only be created on element nodes.");
113
+
114
+ if NIL_P(ns)
115
+ {
116
+ xattr = xmlNewProp(xnode, (xmlChar*)StringValuePtr(name), (xmlChar*)StringValuePtr(value));
117
+ }
118
+ else
119
+ {
120
+ xmlNsPtr xns;
121
+ Data_Get_Struct(ns, xmlNs, xns);
122
+ xattr = xmlNewNsProp(xnode, xns, (xmlChar*)StringValuePtr(name), (xmlChar*)StringValuePtr(value));
123
+ }
124
+
125
+ if (!xattr)
126
+ rb_raise(rb_eRuntimeError, "Could not create attribute.");
127
+
128
+ xattr->_private = (void *) self;
129
+ DATA_PTR( self) = xattr;
130
+ return self;
131
+ }
132
+
133
+ /*
134
+ * call-seq:
135
+ * attr.child -> node
136
+ *
137
+ * Obtain this attribute's child attribute(s).
138
+ */
139
+ static VALUE rxml_attr_child_get(VALUE self)
140
+ {
141
+ xmlAttrPtr xattr;
142
+ Data_Get_Struct(self, xmlAttr, xattr);
143
+ if (xattr->children == NULL)
144
+ return (Qnil);
145
+ else
146
+ return (rxml_node_wrap(cXMLNode, (xmlNodePtr) xattr->children));
147
+ }
148
+
149
+ /*
150
+ * call-seq:
151
+ * attr.child? -> (true|false)
152
+ *
153
+ * Returns whether this attribute has child attributes.
154
+ */
155
+ static VALUE rxml_attr_child_q(VALUE self)
156
+ {
157
+ xmlAttrPtr xattr;
158
+ Data_Get_Struct(self, xmlAttr, xattr);
159
+ if (xattr->children == NULL)
160
+ return (Qfalse);
161
+ else
162
+ return (Qtrue);
163
+ }
164
+
165
+ /*
166
+ * call-seq:
167
+ * attr.doc -> XML::Document
168
+ *
169
+ * Returns this attribute's document.
170
+ *
171
+ * doc.root.attributes.get_attribute('name').doc == doc
172
+ */
173
+ static VALUE rxml_attr_doc_get(VALUE self)
174
+ {
175
+ xmlAttrPtr xattr;
176
+ Data_Get_Struct(self, xmlAttr, xattr);
177
+ if (xattr->doc == NULL)
178
+ return (Qnil);
179
+ else
180
+ return (rxml_document_wrap(xattr->doc));
181
+ }
182
+
183
+ /*
184
+ * call-seq:
185
+ * attr.doc? -> (true|false)
186
+ *
187
+ * Determine whether this attribute is associated with an
188
+ * XML::Document.
189
+ */
190
+ static VALUE rxml_attr_doc_q(VALUE self)
191
+ {
192
+ xmlAttrPtr xattr;
193
+ Data_Get_Struct(self, xmlAttr, xattr);
194
+ if (xattr->doc == NULL)
195
+ return (Qfalse);
196
+ else
197
+ return (Qtrue);
198
+ }
199
+
200
+ /*
201
+ * call-seq:
202
+ * attr.last -> node
203
+ *
204
+ * Obtain the last attribute.
205
+ */
206
+ static VALUE rxml_attr_last_get(VALUE self)
207
+ {
208
+ xmlAttrPtr xattr;
209
+ Data_Get_Struct(self, xmlAttr, xattr);
210
+ if (xattr->last == NULL)
211
+ return (Qnil);
212
+ else
213
+ return (rxml_node_wrap(cXMLNode, xattr->last));
214
+ }
215
+
216
+ /*
217
+ * call-seq:
218
+ * attr.last? -> (true|false)
219
+ *
220
+ * Determine whether this is the last attribute.
221
+ */
222
+ static VALUE rxml_attr_last_q(VALUE self)
223
+ {
224
+ xmlAttrPtr xattr;
225
+ Data_Get_Struct(self, xmlAttr, xattr);
226
+ if (xattr->last == NULL)
227
+ return (Qfalse);
228
+ else
229
+ return (Qtrue);
230
+ }
231
+
232
+ /*
233
+ * call-seq:
234
+ * attr.name -> "name"
235
+ *
236
+ * Obtain this attribute's name.
237
+ */
238
+ static VALUE rxml_attr_name_get(VALUE self)
239
+ {
240
+ xmlAttrPtr xattr;
241
+ Data_Get_Struct(self, xmlAttr, xattr);
242
+
243
+ if (xattr->name == NULL)
244
+ return (Qnil);
245
+ else
246
+ return (rb_str_new2((const char*) xattr->name));
247
+ }
248
+
249
+ /*
250
+ * call-seq:
251
+ * attr.next -> node
252
+ *
253
+ * Obtain the next attribute.
254
+ */
255
+ static VALUE rxml_attr_next_get(VALUE self)
256
+ {
257
+ xmlAttrPtr xattr;
258
+ Data_Get_Struct(self, xmlAttr, xattr);
259
+ if (xattr->next == NULL)
260
+ return (Qnil);
261
+ else
262
+ return (rxml_attr_wrap(xattr->next));
263
+ }
264
+
265
+ /*
266
+ * call-seq:
267
+ * attr.next? -> (true|false)
268
+ *
269
+ * Determine whether there is a next attribute.
270
+ */
271
+ static VALUE rxml_attr_next_q(VALUE self)
272
+ {
273
+ xmlAttrPtr xattr;
274
+ Data_Get_Struct(self, xmlAttr, xattr);
275
+ if (xattr->next == NULL)
276
+ return (Qfalse);
277
+ else
278
+ return (Qtrue);
279
+ }
280
+
281
+ /*
282
+ * call-seq:
283
+ * attr.type_name -> "attribute"
284
+ *
285
+ * Obtain this attribute node's type name.
286
+ */
287
+ static VALUE rxml_attr_node_type_name(VALUE self)
288
+ {
289
+ return (rb_str_new2("attribute"));
290
+ }
291
+
292
+ /*
293
+ * call-seq:
294
+ * attr.ns -> namespace
295
+ *
296
+ * Obtain this attribute's associated XML::NS, if any.
297
+ */
298
+ static VALUE rxml_attr_ns_get(VALUE self)
299
+ {
300
+ xmlAttrPtr xattr;
301
+ Data_Get_Struct(self, xmlAttr, xattr);
302
+ if (xattr->ns == NULL)
303
+ return (Qnil);
304
+ else
305
+ return (rxml_ns_wrap(xattr->ns));
306
+ }
307
+
308
+ /*
309
+ * call-seq:
310
+ * attr.ns? -> (true|false)
311
+ *
312
+ * Determine whether this attribute has an associated
313
+ * namespace.
314
+ */
315
+ static VALUE rxml_attr_ns_q(VALUE self)
316
+ {
317
+ xmlAttrPtr xattr;
318
+ Data_Get_Struct(self, xmlAttr, xattr);
319
+ if (xattr->ns == NULL)
320
+ return (Qfalse);
321
+ else
322
+ return (Qtrue);
323
+ }
324
+
325
+ /*
326
+ * call-seq:
327
+ * attr.parent -> node
328
+ *
329
+ * Obtain this attribute node's parent.
330
+ */
331
+ static VALUE rxml_attr_parent_get(VALUE self)
332
+ {
333
+ xmlAttrPtr xattr;
334
+ Data_Get_Struct(self, xmlAttr, xattr);
335
+ if (xattr->parent == NULL)
336
+ return (Qnil);
337
+ else
338
+ return (rxml_node_wrap(cXMLNode, xattr->parent));
339
+ }
340
+
341
+ /*
342
+ * call-seq:
343
+ * attr.parent? -> (true|false)
344
+ *
345
+ * Determine whether this attribute has a parent.
346
+ */
347
+ static VALUE rxml_attr_parent_q(VALUE self)
348
+ {
349
+ xmlAttrPtr xattr;
350
+ Data_Get_Struct(self, xmlAttr, xattr);
351
+ if (xattr->parent == NULL)
352
+ return (Qfalse);
353
+ else
354
+ return (Qtrue);
355
+ }
356
+
357
+ /*
358
+ * call-seq:
359
+ * attr.prev -> node
360
+ *
361
+ * Obtain the previous attribute.
362
+ */
363
+ static VALUE rxml_attr_prev_get(VALUE self)
364
+ {
365
+ xmlAttrPtr xattr;
366
+ Data_Get_Struct(self, xmlAttr, xattr);
367
+ if (xattr->prev == NULL)
368
+ return (Qnil);
369
+ else
370
+ return (rxml_attr_wrap(xattr->prev));
371
+ }
372
+
373
+ /*
374
+ * call-seq:
375
+ * attr.prev? -> (true|false)
376
+ *
377
+ * Determine whether there is a previous attribute.
378
+ */
379
+ static VALUE rxml_attr_prev_q(VALUE self)
380
+ {
381
+ xmlAttrPtr xattr;
382
+ Data_Get_Struct(self, xmlAttr, xattr);
383
+ if (xattr->prev == NULL)
384
+ return (Qfalse);
385
+ else
386
+ return (Qtrue);
387
+ }
388
+
389
+ /*
390
+ * call-seq:
391
+ * node.remove! -> nil
392
+ *
393
+ * Removes this attribute from it's parent.
394
+ */
395
+ static VALUE rxml_attr_remove_ex(VALUE self)
396
+ {
397
+ xmlAttrPtr xattr;
398
+ Data_Get_Struct(self, xmlAttr, xattr);
399
+
400
+ if (xattr->_private == NULL)
401
+ xmlRemoveProp(xattr);
402
+ else
403
+ xmlUnlinkNode((xmlNodePtr) xattr);
404
+
405
+ return (Qnil);
406
+ }
407
+
408
+ /*
409
+ * call-seq:
410
+ * attr.value -> "value"
411
+ *
412
+ * Obtain the value of this attribute.
413
+ */
414
+ VALUE rxml_attr_value_get(VALUE self)
415
+ {
416
+ xmlAttrPtr xattr;
417
+ xmlChar *value;
418
+ VALUE result = Qnil;
419
+
420
+ Data_Get_Struct(self, xmlAttr, xattr);
421
+ if (rxml_attr_parent_q(self) == Qtrue)
422
+ {
423
+ value = xmlGetProp(xattr->parent, xattr->name);
424
+ if (value != NULL)
425
+ {
426
+ result = rb_str_new2((const char*) value);
427
+ xmlFree(value);
428
+ }
429
+ }
430
+ return (result);
431
+ }
432
+
433
+ /*
434
+ * call-seq:
435
+ * attr.value = "value"
436
+ *
437
+ * Sets the value of this attribute.
438
+ */
439
+ VALUE rxml_attr_value_set(VALUE self, VALUE val)
440
+ {
441
+ xmlAttrPtr xattr;
442
+
443
+ Check_Type(val, T_STRING);
444
+ Data_Get_Struct(self, xmlAttr, xattr);
445
+
446
+ if (xattr->ns)
447
+ xmlSetNsProp(xattr->parent, xattr->ns, xattr->name,
448
+ (xmlChar*) StringValuePtr(val));
449
+ else
450
+ xmlSetProp(xattr->parent, xattr->name, (xmlChar*) StringValuePtr(val));
451
+
452
+ return (self);
453
+ }
454
+
455
+ // Rdoc needs to know
456
+ #ifdef RDOC_NEVER_DEFINED
457
+ mLibXML = rb_define_module("LibXML");
458
+ mXML = rb_define_module_under(mLibXML, "XML");
459
+ #endif
460
+
461
+ void ruby_init_xml_attr(void)
462
+ {
463
+ cXMLAttr = rb_define_class_under(mXML, "Attr", rb_cObject);
464
+ rb_define_alloc_func(cXMLAttr, rxml_attr_alloc);
465
+ rb_define_method(cXMLAttr, "initialize", rxml_attr_initialize, -1);
466
+ rb_define_method(cXMLAttr, "child", rxml_attr_child_get, 0);
467
+ rb_define_method(cXMLAttr, "child?", rxml_attr_child_q, 0);
468
+ rb_define_method(cXMLAttr, "doc", rxml_attr_doc_get, 0);
469
+ rb_define_method(cXMLAttr, "doc?", rxml_attr_doc_q, 0);
470
+ rb_define_method(cXMLAttr, "last", rxml_attr_last_get, 0);
471
+ rb_define_method(cXMLAttr, "last?", rxml_attr_last_q, 0);
472
+ rb_define_method(cXMLAttr, "name", rxml_attr_name_get, 0);
473
+ rb_define_method(cXMLAttr, "next", rxml_attr_next_get, 0);
474
+ rb_define_method(cXMLAttr, "next?", rxml_attr_next_q, 0);
475
+ rb_define_method(cXMLAttr, "node_type_name", rxml_attr_node_type_name, 0);
476
+ rb_define_method(cXMLAttr, "ns", rxml_attr_ns_get, 0);
477
+ rb_define_method(cXMLAttr, "ns?", rxml_attr_ns_q, 0);
478
+ rb_define_method(cXMLAttr, "parent", rxml_attr_parent_get, 0);
479
+ rb_define_method(cXMLAttr, "parent?", rxml_attr_parent_q, 0);
480
+ rb_define_method(cXMLAttr, "prev", rxml_attr_prev_get, 0);
481
+ rb_define_method(cXMLAttr, "prev?", rxml_attr_prev_q, 0);
482
+ rb_define_method(cXMLAttr, "remove!", rxml_attr_remove_ex, 0);
483
+ rb_define_method(cXMLAttr, "value", rxml_attr_value_get, 0);
484
+ rb_define_method(cXMLAttr, "value=", rxml_attr_value_set, 1);
485
+ }