libxml-ruby 2.8.0 → 2.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY +15 -0
  3. data/README.rdoc +7 -7
  4. data/Rakefile +80 -78
  5. data/ext/libxml/extconf.h +4 -0
  6. data/ext/libxml/extconf.rb +57 -116
  7. data/ext/libxml/libxml.c +4 -0
  8. data/ext/libxml/ruby_xml.c +977 -893
  9. data/ext/libxml/ruby_xml.h +20 -10
  10. data/ext/libxml/ruby_xml_attr.c +333 -333
  11. data/ext/libxml/ruby_xml_attr_decl.c +2 -2
  12. data/ext/libxml/ruby_xml_cbg.c +85 -85
  13. data/ext/libxml/ruby_xml_document.c +1133 -1147
  14. data/ext/libxml/ruby_xml_dtd.c +261 -268
  15. data/ext/libxml/ruby_xml_encoding.c +262 -260
  16. data/ext/libxml/ruby_xml_encoding.h +19 -19
  17. data/ext/libxml/ruby_xml_html_parser_context.c +337 -338
  18. data/ext/libxml/ruby_xml_input_cbg.c +191 -191
  19. data/ext/libxml/ruby_xml_io.c +52 -50
  20. data/ext/libxml/ruby_xml_namespace.c +2 -2
  21. data/ext/libxml/ruby_xml_node.c +1446 -1452
  22. data/ext/libxml/ruby_xml_parser_context.c +999 -1001
  23. data/ext/libxml/ruby_xml_reader.c +1226 -1228
  24. data/ext/libxml/ruby_xml_relaxng.c +110 -111
  25. data/ext/libxml/ruby_xml_sax2_handler.c +326 -328
  26. data/ext/libxml/ruby_xml_schema.c +300 -301
  27. data/ext/libxml/ruby_xml_version.h +3 -3
  28. data/ext/libxml/ruby_xml_writer.c +14 -15
  29. data/ext/libxml/ruby_xml_xpath.c +188 -188
  30. data/ext/libxml/ruby_xml_xpath_context.c +360 -361
  31. data/ext/libxml/ruby_xml_xpath_object.c +335 -335
  32. data/libxml-ruby.gemspec +47 -44
  33. data/test/tc_attr.rb +5 -7
  34. data/test/tc_attr_decl.rb +5 -6
  35. data/test/tc_attributes.rb +1 -2
  36. data/test/tc_canonicalize.rb +1 -2
  37. data/test/tc_deprecated_require.rb +1 -2
  38. data/test/tc_document.rb +4 -5
  39. data/test/tc_document_write.rb +2 -3
  40. data/test/tc_dtd.rb +4 -5
  41. data/test/tc_encoding.rb +126 -126
  42. data/test/tc_encoding_sax.rb +4 -3
  43. data/test/tc_error.rb +14 -15
  44. data/test/tc_html_parser.rb +15 -7
  45. data/test/tc_html_parser_context.rb +1 -2
  46. data/test/tc_namespace.rb +2 -3
  47. data/test/tc_namespaces.rb +5 -6
  48. data/test/tc_node.rb +2 -3
  49. data/test/tc_node_cdata.rb +2 -3
  50. data/test/tc_node_comment.rb +1 -2
  51. data/test/tc_node_copy.rb +1 -2
  52. data/test/tc_node_edit.rb +5 -7
  53. data/test/tc_node_pi.rb +1 -2
  54. data/test/tc_node_text.rb +2 -3
  55. data/test/tc_node_write.rb +2 -3
  56. data/test/tc_node_xlink.rb +1 -2
  57. data/test/tc_parser.rb +18 -24
  58. data/test/tc_parser_context.rb +6 -7
  59. data/test/tc_properties.rb +1 -2
  60. data/test/tc_reader.rb +9 -10
  61. data/test/tc_relaxng.rb +4 -5
  62. data/test/tc_sax_parser.rb +9 -10
  63. data/test/tc_schema.rb +4 -5
  64. data/test/tc_traversal.rb +1 -2
  65. data/test/tc_writer.rb +1 -2
  66. data/test/tc_xinclude.rb +1 -2
  67. data/test/tc_xml.rb +1 -2
  68. data/test/tc_xpath.rb +8 -9
  69. data/test/tc_xpath_context.rb +3 -4
  70. data/test/tc_xpath_expression.rb +3 -4
  71. data/test/tc_xpointer.rb +1 -3
  72. data/test/test_helper.rb +3 -1
  73. data/test/test_suite.rb +0 -1
  74. metadata +47 -11
  75. data/test/etc_doc_to_s.rb +0 -21
  76. data/test/ets_doc_file.rb +0 -17
  77. data/test/ets_doc_to_s.rb +0 -23
  78. data/test/ets_gpx.rb +0 -28
  79. data/test/ets_node_gc.rb +0 -23
  80. data/test/ets_test.xml +0 -2
  81. data/test/ets_tsr.rb +0 -11
@@ -1,10 +1,20 @@
1
- /* Please see the LICENSE file for copyright and distribution information */
2
-
3
- #ifndef __RUBY_XML_H__
4
- #define __RUBY_XML_H__
5
-
6
- extern VALUE mXML;
7
- int rxml_libxml_default_options();
8
- void rxml_init_xml(void);
9
-
10
- #endif
1
+ /* Please see the LICENSE file for copyright and distribution information */
2
+
3
+ #ifndef __RUBY_XML_H__
4
+ #define __RUBY_XML_H__
5
+
6
+ extern VALUE mXML;
7
+ int rxml_libxml_default_options();
8
+ void rxml_init_xml(void);
9
+
10
+ void rxml_register_node(xmlNodePtr node, VALUE value);
11
+ void rxml_register_doc(xmlDocPtr doc, VALUE value);
12
+ void rxml_register_dtd(xmlDtdPtr dtd, VALUE value);
13
+ void rxml_unregister_node(xmlNodePtr node);
14
+ void rxml_unregister_doc(xmlDocPtr doc);
15
+ void rxml_unregister_dtd(xmlDtdPtr dtd);
16
+ VALUE rxml_lookup_node(xmlNodePtr node);
17
+ VALUE rxml_lookup_doc(xmlDocPtr doc);
18
+ VALUE rxml_lookup_dtd(xmlDtdPtr dtd);
19
+
20
+ #endif
@@ -1,333 +1,333 @@
1
- /* Please see the LICENSE file for copyright and distribution information */
2
-
3
- /*
4
- * Document-class: LibXML::XML::Attr
5
- *
6
- * Provides access to an attribute defined on an element.
7
- *
8
- * Basic Usage:
9
- *
10
- * require 'test_helper'
11
- *
12
- * doc = XML::Document.new(<some_file>)
13
- * attribute = doc.root.attributes.get_attribute_ns('http://www.w3.org/1999/xlink', 'href')
14
- * attribute.name == 'href'
15
- * attribute.value == 'http://www.mydocument.com'
16
- * attribute.remove!
17
- */
18
-
19
- /* Attributes are owned and freed by their nodes. Thus, its easier for the
20
- ruby bindings to not manage attribute memory management. This does mean
21
- that accessing a particular attribute multiple times will return multiple
22
- different ruby objects. Since we are not using free or xnode->_private
23
- this works out fine. Previous versions of the bindings had a one to
24
- one mapping between ruby object and xml attribute, but that could
25
- result in segfaults because the ruby object could be gc'ed. In theory
26
- the mark method on the parent node could prevent that, but if an
27
- attribute is returned using an xpath statement then the node would
28
- never by surfaced to ruby and the mark method never called. */
29
-
30
- #include "ruby_libxml.h"
31
- #include "ruby_xml_attr.h"
32
-
33
- VALUE cXMLAttr;
34
-
35
- void rxml_attr_mark(xmlAttrPtr xattr)
36
- {
37
- /* This can happen if Ruby does a GC run after creating the
38
- new attribute but before initializing it. */
39
- if (xattr != NULL)
40
- rxml_node_mark((xmlNodePtr) xattr);
41
- }
42
-
43
- VALUE rxml_attr_wrap(xmlAttrPtr xattr)
44
- {
45
- return Data_Wrap_Struct(cXMLAttr, rxml_attr_mark, NULL, xattr);
46
- }
47
-
48
- static VALUE rxml_attr_alloc(VALUE klass)
49
- {
50
- return Data_Wrap_Struct(klass, rxml_attr_mark, NULL, NULL);
51
- }
52
-
53
- /*
54
- * call-seq:
55
- * attr.initialize(node, "name", "value")
56
- *
57
- * Creates a new attribute for the node.
58
- *
59
- * node: The XML::Node that will contain the attribute
60
- * name: The name of the attribute
61
- * value: The value of the attribute
62
- *
63
- * attr = XML::Attr.new(doc.root, 'name', 'libxml')
64
- */
65
- static VALUE rxml_attr_initialize(int argc, VALUE *argv, VALUE self)
66
- {
67
- VALUE node = argv[0];
68
- VALUE name = argv[1];
69
- VALUE value = argv[2];
70
- VALUE ns = (argc == 4 ? argv[3] : Qnil);
71
-
72
- xmlNodePtr xnode;
73
- xmlAttrPtr xattr;
74
-
75
- if (argc < 3 || argc > 4)
76
- rb_raise(rb_eArgError, "Wrong number of arguments (3 or 4)");
77
-
78
- Check_Type(name, T_STRING);
79
- Check_Type(value, T_STRING);
80
-
81
- Data_Get_Struct(node, xmlNode, xnode);
82
-
83
- if (xnode->type != XML_ELEMENT_NODE)
84
- rb_raise(rb_eArgError, "Attributes can only be created on element nodes.");
85
-
86
- if (NIL_P(ns))
87
- {
88
- xattr = xmlNewProp(xnode, (xmlChar*)StringValuePtr(name), (xmlChar*)StringValuePtr(value));
89
- }
90
- else
91
- {
92
- xmlNsPtr xns;
93
- Data_Get_Struct(ns, xmlNs, xns);
94
- xattr = xmlNewNsProp(xnode, xns, (xmlChar*)StringValuePtr(name), (xmlChar*)StringValuePtr(value));
95
- }
96
-
97
- if (!xattr)
98
- rb_raise(rb_eRuntimeError, "Could not create attribute.");
99
-
100
- DATA_PTR( self) = xattr;
101
- return self;
102
- }
103
-
104
- /*
105
- * call-seq:
106
- * attr.child -> node
107
- *
108
- * Obtain this attribute's child attribute(s).
109
- */
110
- static VALUE rxml_attr_child_get(VALUE self)
111
- {
112
- xmlAttrPtr xattr;
113
- Data_Get_Struct(self, xmlAttr, xattr);
114
- if (xattr->children == NULL)
115
- return Qnil;
116
- else
117
- return rxml_node_wrap((xmlNodePtr) xattr->children);
118
- }
119
-
120
-
121
- /*
122
- * call-seq:
123
- * attr.doc -> XML::Document
124
- *
125
- * Returns this attribute's document.
126
- *
127
- * doc.root.attributes.get_attribute('name').doc == doc
128
- */
129
- static VALUE rxml_attr_doc_get(VALUE self)
130
- {
131
- xmlAttrPtr xattr;
132
- Data_Get_Struct(self, xmlAttr, xattr);
133
- if (xattr->doc == NULL)
134
- return Qnil;
135
- else
136
- return rxml_document_wrap(xattr->doc);
137
- }
138
-
139
- /*
140
- * call-seq:
141
- * attr.last -> node
142
- *
143
- * Obtain the last attribute.
144
- */
145
- static VALUE rxml_attr_last_get(VALUE self)
146
- {
147
- xmlAttrPtr xattr;
148
- Data_Get_Struct(self, xmlAttr, xattr);
149
- if (xattr->last == NULL)
150
- return Qnil;
151
- else
152
- return rxml_node_wrap(xattr->last);
153
- }
154
-
155
- /*
156
- * call-seq:
157
- * attr.name -> "name"
158
- *
159
- * Obtain this attribute's name.
160
- */
161
- static VALUE rxml_attr_name_get(VALUE self)
162
- {
163
- xmlAttrPtr xattr;
164
- Data_Get_Struct(self, xmlAttr, xattr);
165
-
166
- if (xattr->name == NULL)
167
- return Qnil;
168
- else
169
- return rxml_new_cstr((const char*) xattr->name, NULL);
170
- }
171
-
172
- /*
173
- * call-seq:
174
- * attr.next -> node
175
- *
176
- * Obtain the next attribute.
177
- */
178
- static VALUE rxml_attr_next_get(VALUE self)
179
- {
180
- xmlAttrPtr xattr;
181
- Data_Get_Struct(self, xmlAttr, xattr);
182
- if (xattr->next == NULL)
183
- return Qnil;
184
- else
185
- return rxml_attr_wrap(xattr->next);
186
- }
187
-
188
- /*
189
- * call-seq:
190
- * attr.node_type -> num
191
- *
192
- * Obtain this node's type identifier.
193
- */
194
- static VALUE rxml_attr_node_type(VALUE self)
195
- {
196
- xmlAttrPtr xattr;
197
- Data_Get_Struct(self, xmlAttr, xattr);
198
- return INT2NUM(xattr->type);
199
- }
200
-
201
- /*
202
- * call-seq:
203
- * attr.ns -> namespace
204
- *
205
- * Obtain this attribute's associated XML::NS, if any.
206
- */
207
- static VALUE rxml_attr_ns_get(VALUE self)
208
- {
209
- xmlAttrPtr xattr;
210
- Data_Get_Struct(self, xmlAttr, xattr);
211
- if (xattr->ns == NULL)
212
- return Qnil;
213
- else
214
- return rxml_namespace_wrap(xattr->ns);
215
- }
216
-
217
- /*
218
- * call-seq:
219
- * attr.parent -> node
220
- *
221
- * Obtain this attribute node's parent.
222
- */
223
- static VALUE rxml_attr_parent_get(VALUE self)
224
- {
225
- xmlAttrPtr xattr;
226
- Data_Get_Struct(self, xmlAttr, xattr);
227
- if (xattr->parent == NULL)
228
- return Qnil;
229
- else
230
- return rxml_node_wrap(xattr->parent);
231
- }
232
-
233
- /*
234
- * call-seq:
235
- * attr.prev -> node
236
- *
237
- * Obtain the previous attribute.
238
- */
239
- static VALUE rxml_attr_prev_get(VALUE self)
240
- {
241
- xmlAttrPtr xattr;
242
- Data_Get_Struct(self, xmlAttr, xattr);
243
- if (xattr->prev == NULL)
244
- return Qnil;
245
- else
246
- return rxml_attr_wrap(xattr->prev);
247
- }
248
-
249
- /*
250
- * call-seq:
251
- * attr.remove! -> nil
252
- *
253
- * Removes this attribute from it's parent. Note
254
- * the attribute and its content is freed and can
255
- * no longer be used. If you try to use it you
256
- * will get a segmentation fault.
257
- */
258
- static VALUE rxml_attr_remove_ex(VALUE self)
259
- {
260
- xmlAttrPtr xattr;
261
- Data_Get_Struct(self, xmlAttr, xattr);
262
- xmlRemoveProp(xattr);
263
-
264
- RDATA(self)->data = NULL;
265
- RDATA(self)->dfree = NULL;
266
- RDATA(self)->dmark = NULL;
267
-
268
- return Qnil;
269
- }
270
-
271
- /*
272
- * call-seq:
273
- * attr.value -> "value"
274
- *
275
- * Obtain the value of this attribute.
276
- */
277
- VALUE rxml_attr_value_get(VALUE self)
278
- {
279
- xmlAttrPtr xattr;
280
- xmlChar *value;
281
- VALUE result = Qnil;
282
-
283
- Data_Get_Struct(self, xmlAttr, xattr);
284
- value = xmlNodeGetContent((xmlNodePtr)xattr);
285
-
286
- if (value != NULL)
287
- {
288
- result = rxml_new_cstr((const char*) value, NULL);
289
- xmlFree(value);
290
- }
291
- return result;
292
- }
293
-
294
- /*
295
- * call-seq:
296
- * attr.value = "value"
297
- *
298
- * Sets the value of this attribute.
299
- */
300
- VALUE rxml_attr_value_set(VALUE self, VALUE val)
301
- {
302
- xmlAttrPtr xattr;
303
-
304
- Check_Type(val, T_STRING);
305
- Data_Get_Struct(self, xmlAttr, xattr);
306
-
307
- if (xattr->ns)
308
- xmlSetNsProp(xattr->parent, xattr->ns, xattr->name,
309
- (xmlChar*) StringValuePtr(val));
310
- else
311
- xmlSetProp(xattr->parent, xattr->name, (xmlChar*) StringValuePtr(val));
312
-
313
- return (self);
314
- }
315
-
316
- void rxml_init_attr(void)
317
- {
318
- cXMLAttr = rb_define_class_under(mXML, "Attr", rb_cObject);
319
- rb_define_alloc_func(cXMLAttr, rxml_attr_alloc);
320
- rb_define_method(cXMLAttr, "initialize", rxml_attr_initialize, -1);
321
- rb_define_method(cXMLAttr, "child", rxml_attr_child_get, 0);
322
- rb_define_method(cXMLAttr, "doc", rxml_attr_doc_get, 0);
323
- rb_define_method(cXMLAttr, "last", rxml_attr_last_get, 0);
324
- rb_define_method(cXMLAttr, "name", rxml_attr_name_get, 0);
325
- rb_define_method(cXMLAttr, "next", rxml_attr_next_get, 0);
326
- rb_define_method(cXMLAttr, "node_type", rxml_attr_node_type, 0);
327
- rb_define_method(cXMLAttr, "ns", rxml_attr_ns_get, 0);
328
- rb_define_method(cXMLAttr, "parent", rxml_attr_parent_get, 0);
329
- rb_define_method(cXMLAttr, "prev", rxml_attr_prev_get, 0);
330
- rb_define_method(cXMLAttr, "remove!", rxml_attr_remove_ex, 0);
331
- rb_define_method(cXMLAttr, "value", rxml_attr_value_get, 0);
332
- rb_define_method(cXMLAttr, "value=", rxml_attr_value_set, 1);
333
- }
1
+ /* Please see the LICENSE file for copyright and distribution information */
2
+
3
+ /*
4
+ * Document-class: LibXML::XML::Attr
5
+ *
6
+ * Provides access to an attribute defined on an element.
7
+ *
8
+ * Basic Usage:
9
+ *
10
+ * require 'test_helper'
11
+ *
12
+ * doc = XML::Document.new(<some_file>)
13
+ * attribute = doc.root.attributes.get_attribute_ns('http://www.w3.org/1999/xlink', 'href')
14
+ * attribute.name == 'href'
15
+ * attribute.value == 'http://www.mydocument.com'
16
+ * attribute.remove!
17
+ */
18
+
19
+ /* Attributes are owned and freed by their nodes. Thus, its easier for the
20
+ ruby bindings to not manage attribute memory management. This does mean
21
+ that accessing a particular attribute multiple times will return multiple
22
+ different ruby objects. Since we are not using free this works out fine.
23
+ Previous versions of the bindings had a one to one mapping between ruby
24
+ object and xml attribute, but that could result in segfaults because the
25
+ ruby object could be gc'ed. In theory the mark method on the parent node
26
+ could prevent that, but if an attribute is returned using an xpath statement
27
+ then the node would never by surfaced to ruby and the mark method never
28
+ called. */
29
+
30
+ #include "ruby_libxml.h"
31
+ #include "ruby_xml_attr.h"
32
+
33
+ VALUE cXMLAttr;
34
+
35
+ void rxml_attr_mark(xmlAttrPtr xattr)
36
+ {
37
+ /* This can happen if Ruby does a GC run after creating the
38
+ new attribute but before initializing it. */
39
+ if (xattr != NULL)
40
+ rxml_node_mark((xmlNodePtr) xattr);
41
+ }
42
+
43
+ VALUE rxml_attr_wrap(xmlAttrPtr xattr)
44
+ {
45
+ return Data_Wrap_Struct(cXMLAttr, rxml_attr_mark, NULL, xattr);
46
+ }
47
+
48
+ static VALUE rxml_attr_alloc(VALUE klass)
49
+ {
50
+ return Data_Wrap_Struct(klass, rxml_attr_mark, NULL, NULL);
51
+ }
52
+
53
+ /*
54
+ * call-seq:
55
+ * attr.initialize(node, "name", "value")
56
+ *
57
+ * Creates a new attribute for the node.
58
+ *
59
+ * node: The XML::Node that will contain the attribute
60
+ * name: The name of the attribute
61
+ * value: The value of the attribute
62
+ *
63
+ * attr = XML::Attr.new(doc.root, 'name', 'libxml')
64
+ */
65
+ static VALUE rxml_attr_initialize(int argc, VALUE *argv, VALUE self)
66
+ {
67
+ VALUE node = argv[0];
68
+ VALUE name = argv[1];
69
+ VALUE value = argv[2];
70
+ VALUE ns = (argc == 4 ? argv[3] : Qnil);
71
+
72
+ xmlNodePtr xnode;
73
+ xmlAttrPtr xattr;
74
+
75
+ if (argc < 3 || argc > 4)
76
+ rb_raise(rb_eArgError, "Wrong number of arguments (3 or 4)");
77
+
78
+ Check_Type(name, T_STRING);
79
+ Check_Type(value, T_STRING);
80
+
81
+ Data_Get_Struct(node, xmlNode, xnode);
82
+
83
+ if (xnode->type != XML_ELEMENT_NODE)
84
+ rb_raise(rb_eArgError, "Attributes can only be created on element nodes.");
85
+
86
+ if (NIL_P(ns))
87
+ {
88
+ xattr = xmlNewProp(xnode, (xmlChar*)StringValuePtr(name), (xmlChar*)StringValuePtr(value));
89
+ }
90
+ else
91
+ {
92
+ xmlNsPtr xns;
93
+ Data_Get_Struct(ns, xmlNs, xns);
94
+ xattr = xmlNewNsProp(xnode, xns, (xmlChar*)StringValuePtr(name), (xmlChar*)StringValuePtr(value));
95
+ }
96
+
97
+ if (!xattr)
98
+ rb_raise(rb_eRuntimeError, "Could not create attribute.");
99
+
100
+ DATA_PTR( self) = xattr;
101
+ return self;
102
+ }
103
+
104
+ /*
105
+ * call-seq:
106
+ * attr.child -> node
107
+ *
108
+ * Obtain this attribute's child attribute(s).
109
+ */
110
+ static VALUE rxml_attr_child_get(VALUE self)
111
+ {
112
+ xmlAttrPtr xattr;
113
+ Data_Get_Struct(self, xmlAttr, xattr);
114
+ if (xattr->children == NULL)
115
+ return Qnil;
116
+ else
117
+ return rxml_node_wrap((xmlNodePtr) xattr->children);
118
+ }
119
+
120
+
121
+ /*
122
+ * call-seq:
123
+ * attr.doc -> XML::Document
124
+ *
125
+ * Returns this attribute's document.
126
+ *
127
+ * doc.root.attributes.get_attribute('name').doc == doc
128
+ */
129
+ static VALUE rxml_attr_doc_get(VALUE self)
130
+ {
131
+ xmlAttrPtr xattr;
132
+ Data_Get_Struct(self, xmlAttr, xattr);
133
+ if (xattr->doc == NULL)
134
+ return Qnil;
135
+ else
136
+ return rxml_document_wrap(xattr->doc);
137
+ }
138
+
139
+ /*
140
+ * call-seq:
141
+ * attr.last -> node
142
+ *
143
+ * Obtain the last attribute.
144
+ */
145
+ static VALUE rxml_attr_last_get(VALUE self)
146
+ {
147
+ xmlAttrPtr xattr;
148
+ Data_Get_Struct(self, xmlAttr, xattr);
149
+ if (xattr->last == NULL)
150
+ return Qnil;
151
+ else
152
+ return rxml_node_wrap(xattr->last);
153
+ }
154
+
155
+ /*
156
+ * call-seq:
157
+ * attr.name -> "name"
158
+ *
159
+ * Obtain this attribute's name.
160
+ */
161
+ static VALUE rxml_attr_name_get(VALUE self)
162
+ {
163
+ xmlAttrPtr xattr;
164
+ Data_Get_Struct(self, xmlAttr, xattr);
165
+
166
+ if (xattr->name == NULL)
167
+ return Qnil;
168
+ else
169
+ return rxml_new_cstr( xattr->name, NULL);
170
+ }
171
+
172
+ /*
173
+ * call-seq:
174
+ * attr.next -> node
175
+ *
176
+ * Obtain the next attribute.
177
+ */
178
+ static VALUE rxml_attr_next_get(VALUE self)
179
+ {
180
+ xmlAttrPtr xattr;
181
+ Data_Get_Struct(self, xmlAttr, xattr);
182
+ if (xattr->next == NULL)
183
+ return Qnil;
184
+ else
185
+ return rxml_attr_wrap(xattr->next);
186
+ }
187
+
188
+ /*
189
+ * call-seq:
190
+ * attr.node_type -> num
191
+ *
192
+ * Obtain this node's type identifier.
193
+ */
194
+ static VALUE rxml_attr_node_type(VALUE self)
195
+ {
196
+ xmlAttrPtr xattr;
197
+ Data_Get_Struct(self, xmlAttr, xattr);
198
+ return INT2NUM(xattr->type);
199
+ }
200
+
201
+ /*
202
+ * call-seq:
203
+ * attr.ns -> namespace
204
+ *
205
+ * Obtain this attribute's associated XML::NS, if any.
206
+ */
207
+ static VALUE rxml_attr_ns_get(VALUE self)
208
+ {
209
+ xmlAttrPtr xattr;
210
+ Data_Get_Struct(self, xmlAttr, xattr);
211
+ if (xattr->ns == NULL)
212
+ return Qnil;
213
+ else
214
+ return rxml_namespace_wrap(xattr->ns);
215
+ }
216
+
217
+ /*
218
+ * call-seq:
219
+ * attr.parent -> node
220
+ *
221
+ * Obtain this attribute node's parent.
222
+ */
223
+ static VALUE rxml_attr_parent_get(VALUE self)
224
+ {
225
+ xmlAttrPtr xattr;
226
+ Data_Get_Struct(self, xmlAttr, xattr);
227
+ if (xattr->parent == NULL)
228
+ return Qnil;
229
+ else
230
+ return rxml_node_wrap(xattr->parent);
231
+ }
232
+
233
+ /*
234
+ * call-seq:
235
+ * attr.prev -> node
236
+ *
237
+ * Obtain the previous attribute.
238
+ */
239
+ static VALUE rxml_attr_prev_get(VALUE self)
240
+ {
241
+ xmlAttrPtr xattr;
242
+ Data_Get_Struct(self, xmlAttr, xattr);
243
+ if (xattr->prev == NULL)
244
+ return Qnil;
245
+ else
246
+ return rxml_attr_wrap(xattr->prev);
247
+ }
248
+
249
+ /*
250
+ * call-seq:
251
+ * attr.remove! -> nil
252
+ *
253
+ * Removes this attribute from it's parent. Note
254
+ * the attribute and its content is freed and can
255
+ * no longer be used. If you try to use it you
256
+ * will get a segmentation fault.
257
+ */
258
+ static VALUE rxml_attr_remove_ex(VALUE self)
259
+ {
260
+ xmlAttrPtr xattr;
261
+ Data_Get_Struct(self, xmlAttr, xattr);
262
+ xmlRemoveProp(xattr);
263
+
264
+ RDATA(self)->data = NULL;
265
+ RDATA(self)->dfree = NULL;
266
+ RDATA(self)->dmark = NULL;
267
+
268
+ return Qnil;
269
+ }
270
+
271
+ /*
272
+ * call-seq:
273
+ * attr.value -> "value"
274
+ *
275
+ * Obtain the value of this attribute.
276
+ */
277
+ VALUE rxml_attr_value_get(VALUE self)
278
+ {
279
+ xmlAttrPtr xattr;
280
+ xmlChar *value;
281
+ VALUE result = Qnil;
282
+
283
+ Data_Get_Struct(self, xmlAttr, xattr);
284
+ value = xmlNodeGetContent((xmlNodePtr)xattr);
285
+
286
+ if (value != NULL)
287
+ {
288
+ result = rxml_new_cstr( value, NULL);
289
+ xmlFree(value);
290
+ }
291
+ return result;
292
+ }
293
+
294
+ /*
295
+ * call-seq:
296
+ * attr.value = "value"
297
+ *
298
+ * Sets the value of this attribute.
299
+ */
300
+ VALUE rxml_attr_value_set(VALUE self, VALUE val)
301
+ {
302
+ xmlAttrPtr xattr;
303
+
304
+ Check_Type(val, T_STRING);
305
+ Data_Get_Struct(self, xmlAttr, xattr);
306
+
307
+ if (xattr->ns)
308
+ xmlSetNsProp(xattr->parent, xattr->ns, xattr->name,
309
+ (xmlChar*) StringValuePtr(val));
310
+ else
311
+ xmlSetProp(xattr->parent, xattr->name, (xmlChar*) StringValuePtr(val));
312
+
313
+ return (self);
314
+ }
315
+
316
+ void rxml_init_attr(void)
317
+ {
318
+ cXMLAttr = rb_define_class_under(mXML, "Attr", rb_cObject);
319
+ rb_define_alloc_func(cXMLAttr, rxml_attr_alloc);
320
+ rb_define_method(cXMLAttr, "initialize", rxml_attr_initialize, -1);
321
+ rb_define_method(cXMLAttr, "child", rxml_attr_child_get, 0);
322
+ rb_define_method(cXMLAttr, "doc", rxml_attr_doc_get, 0);
323
+ rb_define_method(cXMLAttr, "last", rxml_attr_last_get, 0);
324
+ rb_define_method(cXMLAttr, "name", rxml_attr_name_get, 0);
325
+ rb_define_method(cXMLAttr, "next", rxml_attr_next_get, 0);
326
+ rb_define_method(cXMLAttr, "node_type", rxml_attr_node_type, 0);
327
+ rb_define_method(cXMLAttr, "ns", rxml_attr_ns_get, 0);
328
+ rb_define_method(cXMLAttr, "parent", rxml_attr_parent_get, 0);
329
+ rb_define_method(cXMLAttr, "prev", rxml_attr_prev_get, 0);
330
+ rb_define_method(cXMLAttr, "remove!", rxml_attr_remove_ex, 0);
331
+ rb_define_method(cXMLAttr, "value", rxml_attr_value_get, 0);
332
+ rb_define_method(cXMLAttr, "value=", rxml_attr_value_set, 1);
333
+ }