libxml-ruby 2.8.0 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
+ }