coupa-libxml-ruby 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (280) hide show
  1. data/CHANGES +488 -0
  2. data/LICENSE +22 -0
  3. data/README +161 -0
  4. data/Rakefile +188 -0
  5. data/doc/css/normal.css +182 -0
  6. data/doc/img/raze-tiny.png +0 -0
  7. data/doc/img/red-cube.jpg +0 -0
  8. data/doc/img/xml-ruby.png +0 -0
  9. data/doc/index.xml +43 -0
  10. data/doc/install.xml +77 -0
  11. data/doc/layout.rhtml +38 -0
  12. data/doc/layout.xsl +67 -0
  13. data/doc/license.xml +32 -0
  14. data/doc/log/changelog.xml +1324 -0
  15. data/doc/log/changelog.xsl +42 -0
  16. data/doc/rdoc/classes/LibXML.html +207 -0
  17. data/doc/rdoc/classes/LibXML/XML.html +407 -0
  18. data/doc/rdoc/classes/LibXML/XML/Attr.html +521 -0
  19. data/doc/rdoc/classes/LibXML/XML/AttrDecl.html +360 -0
  20. data/doc/rdoc/classes/LibXML/XML/Attributes.html +149 -0
  21. data/doc/rdoc/classes/LibXML/XML/Document.html +460 -0
  22. data/doc/rdoc/classes/LibXML/XML/Error.html +129 -0
  23. data/doc/rdoc/classes/LibXML/XML/HTMLParser.html +263 -0
  24. data/doc/rdoc/classes/LibXML/XML/Namespace.html +248 -0
  25. data/doc/rdoc/classes/LibXML/XML/Namespaces.html +200 -0
  26. data/doc/rdoc/classes/LibXML/XML/Node.html +1351 -0
  27. data/doc/rdoc/classes/LibXML/XML/Parser.html +328 -0
  28. data/doc/rdoc/classes/LibXML/XML/Reader.html +172 -0
  29. data/doc/rdoc/classes/LibXML/XML/SaxParser.html +232 -0
  30. data/doc/rdoc/classes/LibXML/XML/SaxParser/Callbacks.html +506 -0
  31. data/doc/rdoc/classes/LibXML/XML/SaxParser/VerboseCallbacks.html +555 -0
  32. data/doc/rdoc/classes/LibXML/XML/XPath.html +111 -0
  33. data/doc/rdoc/classes/LibXML/XML/XPath/Object.html +162 -0
  34. data/doc/rdoc/classes/cXMLDtd.html +114 -0
  35. data/doc/rdoc/classes/cXMLNode.html +114 -0
  36. data/doc/rdoc/created.rid +1 -0
  37. data/doc/rdoc/files/CHANGES.html +794 -0
  38. data/doc/rdoc/files/LICENSE.html +131 -0
  39. data/doc/rdoc/files/README.html +343 -0
  40. data/doc/rdoc/files/ext/libxml/libxml_c.html +101 -0
  41. data/doc/rdoc/files/ext/libxml/ruby_xml_attr_c.html +101 -0
  42. data/doc/rdoc/files/ext/libxml/ruby_xml_attr_decl_c.html +101 -0
  43. data/doc/rdoc/files/ext/libxml/ruby_xml_attributes_c.html +101 -0
  44. data/doc/rdoc/files/ext/libxml/ruby_xml_c.html +101 -0
  45. data/doc/rdoc/files/ext/libxml/ruby_xml_cbg_c.html +101 -0
  46. data/doc/rdoc/files/ext/libxml/ruby_xml_document_c.html +101 -0
  47. data/doc/rdoc/files/ext/libxml/ruby_xml_dtd_c.html +101 -0
  48. data/doc/rdoc/files/ext/libxml/ruby_xml_encoding_c.html +101 -0
  49. data/doc/rdoc/files/ext/libxml/ruby_xml_error_c.html +101 -0
  50. data/doc/rdoc/files/ext/libxml/ruby_xml_html_parser_c.html +101 -0
  51. data/doc/rdoc/files/ext/libxml/ruby_xml_html_parser_context_c.html +101 -0
  52. data/doc/rdoc/files/ext/libxml/ruby_xml_html_parser_options_c.html +101 -0
  53. data/doc/rdoc/files/ext/libxml/ruby_xml_input_cbg_c.html +101 -0
  54. data/doc/rdoc/files/ext/libxml/ruby_xml_io_c.html +101 -0
  55. data/doc/rdoc/files/ext/libxml/ruby_xml_namespace_c.html +101 -0
  56. data/doc/rdoc/files/ext/libxml/ruby_xml_namespaces_c.html +101 -0
  57. data/doc/rdoc/files/ext/libxml/ruby_xml_node_c.html +101 -0
  58. data/doc/rdoc/files/ext/libxml/ruby_xml_parser_c.html +101 -0
  59. data/doc/rdoc/files/ext/libxml/ruby_xml_parser_context_c.html +101 -0
  60. data/doc/rdoc/files/ext/libxml/ruby_xml_parser_options_c.html +101 -0
  61. data/doc/rdoc/files/ext/libxml/ruby_xml_reader_c.html +101 -0
  62. data/doc/rdoc/files/ext/libxml/ruby_xml_relaxng_c.html +101 -0
  63. data/doc/rdoc/files/ext/libxml/ruby_xml_sax2_handler_c.html +101 -0
  64. data/doc/rdoc/files/ext/libxml/ruby_xml_sax_parser_c.html +101 -0
  65. data/doc/rdoc/files/ext/libxml/ruby_xml_schema_c.html +101 -0
  66. data/doc/rdoc/files/ext/libxml/ruby_xml_xinclude_c.html +101 -0
  67. data/doc/rdoc/files/ext/libxml/ruby_xml_xpath_c.html +101 -0
  68. data/doc/rdoc/files/ext/libxml/ruby_xml_xpath_context_c.html +101 -0
  69. data/doc/rdoc/files/ext/libxml/ruby_xml_xpath_expression_c.html +101 -0
  70. data/doc/rdoc/files/ext/libxml/ruby_xml_xpath_object_c.html +101 -0
  71. data/doc/rdoc/files/ext/libxml/ruby_xml_xpointer_c.html +101 -0
  72. data/doc/rdoc/files/lib/libxml/attr_decl_rb.html +101 -0
  73. data/doc/rdoc/files/lib/libxml/attr_rb.html +101 -0
  74. data/doc/rdoc/files/lib/libxml/attributes_rb.html +101 -0
  75. data/doc/rdoc/files/lib/libxml/document_rb.html +101 -0
  76. data/doc/rdoc/files/lib/libxml/error_rb.html +101 -0
  77. data/doc/rdoc/files/lib/libxml/hpricot_rb.html +192 -0
  78. data/doc/rdoc/files/lib/libxml/html_parser_rb.html +101 -0
  79. data/doc/rdoc/files/lib/libxml/namespace_rb.html +101 -0
  80. data/doc/rdoc/files/lib/libxml/namespaces_rb.html +101 -0
  81. data/doc/rdoc/files/lib/libxml/node_rb.html +108 -0
  82. data/doc/rdoc/files/lib/libxml/ns_rb.html +101 -0
  83. data/doc/rdoc/files/lib/libxml/parser_rb.html +101 -0
  84. data/doc/rdoc/files/lib/libxml/properties_rb.html +101 -0
  85. data/doc/rdoc/files/lib/libxml/reader_rb.html +101 -0
  86. data/doc/rdoc/files/lib/libxml/sax_callbacks_rb.html +101 -0
  87. data/doc/rdoc/files/lib/libxml/sax_parser_rb.html +101 -0
  88. data/doc/rdoc/files/lib/libxml/tree_rb.html +101 -0
  89. data/doc/rdoc/files/lib/libxml/xpath_object_rb.html +101 -0
  90. data/doc/rdoc/files/lib/libxml_rb.html +133 -0
  91. data/doc/rdoc/files/lib/xml/libxml_rb.html +124 -0
  92. data/doc/rdoc/files/lib/xml_rb.html +134 -0
  93. data/doc/rdoc/fr_class_index.html +46 -0
  94. data/doc/rdoc/fr_file_index.html +84 -0
  95. data/doc/rdoc/fr_method_index.html +155 -0
  96. data/doc/rdoc/index.html +24 -0
  97. data/doc/rdoc/rdoc-style.css +208 -0
  98. data/ext/libxml/Makefile +157 -0
  99. data/ext/libxml/build.log +4 -0
  100. data/ext/libxml/extconf.h +5 -0
  101. data/ext/libxml/extconf.rb +278 -0
  102. data/ext/libxml/libxml.c +77 -0
  103. data/ext/libxml/libxml.o +0 -0
  104. data/ext/libxml/libxml_ruby.bundle +0 -0
  105. data/ext/libxml/mkmf.log +228 -0
  106. data/ext/libxml/ruby_libxml.h +93 -0
  107. data/ext/libxml/ruby_xml.c +893 -0
  108. data/ext/libxml/ruby_xml.h +10 -0
  109. data/ext/libxml/ruby_xml.o +0 -0
  110. data/ext/libxml/ruby_xml_attr.c +352 -0
  111. data/ext/libxml/ruby_xml_attr.h +14 -0
  112. data/ext/libxml/ruby_xml_attr.o +0 -0
  113. data/ext/libxml/ruby_xml_attr_decl.c +171 -0
  114. data/ext/libxml/ruby_xml_attr_decl.h +13 -0
  115. data/ext/libxml/ruby_xml_attr_decl.o +0 -0
  116. data/ext/libxml/ruby_xml_attributes.c +277 -0
  117. data/ext/libxml/ruby_xml_attributes.h +17 -0
  118. data/ext/libxml/ruby_xml_attributes.o +0 -0
  119. data/ext/libxml/ruby_xml_cbg.c +86 -0
  120. data/ext/libxml/ruby_xml_cbg.o +0 -0
  121. data/ext/libxml/ruby_xml_document.c +1006 -0
  122. data/ext/libxml/ruby_xml_document.c.old +936 -0
  123. data/ext/libxml/ruby_xml_document.h +17 -0
  124. data/ext/libxml/ruby_xml_document.o +0 -0
  125. data/ext/libxml/ruby_xml_dtd.c +257 -0
  126. data/ext/libxml/ruby_xml_dtd.h +9 -0
  127. data/ext/libxml/ruby_xml_dtd.o +0 -0
  128. data/ext/libxml/ruby_xml_encoding.c +134 -0
  129. data/ext/libxml/ruby_xml_encoding.h +12 -0
  130. data/ext/libxml/ruby_xml_encoding.o +0 -0
  131. data/ext/libxml/ruby_xml_error.c +1004 -0
  132. data/ext/libxml/ruby_xml_error.h +14 -0
  133. data/ext/libxml/ruby_xml_error.o +0 -0
  134. data/ext/libxml/ruby_xml_html_parser.c +92 -0
  135. data/ext/libxml/ruby_xml_html_parser.h +12 -0
  136. data/ext/libxml/ruby_xml_html_parser.o +0 -0
  137. data/ext/libxml/ruby_xml_html_parser_context.c +308 -0
  138. data/ext/libxml/ruby_xml_html_parser_context.h +12 -0
  139. data/ext/libxml/ruby_xml_html_parser_context.o +0 -0
  140. data/ext/libxml/ruby_xml_html_parser_options.c +40 -0
  141. data/ext/libxml/ruby_xml_html_parser_options.h +12 -0
  142. data/ext/libxml/ruby_xml_html_parser_options.o +0 -0
  143. data/ext/libxml/ruby_xml_input_cbg.c +191 -0
  144. data/ext/libxml/ruby_xml_input_cbg.h +20 -0
  145. data/ext/libxml/ruby_xml_input_cbg.o +0 -0
  146. data/ext/libxml/ruby_xml_io.c +30 -0
  147. data/ext/libxml/ruby_xml_io.h +9 -0
  148. data/ext/libxml/ruby_xml_io.o +0 -0
  149. data/ext/libxml/ruby_xml_namespace.c +170 -0
  150. data/ext/libxml/ruby_xml_namespace.h +12 -0
  151. data/ext/libxml/ruby_xml_namespace.o +0 -0
  152. data/ext/libxml/ruby_xml_namespaces.c +295 -0
  153. data/ext/libxml/ruby_xml_namespaces.h +11 -0
  154. data/ext/libxml/ruby_xml_namespaces.o +0 -0
  155. data/ext/libxml/ruby_xml_node.c +1386 -0
  156. data/ext/libxml/ruby_xml_node.h +13 -0
  157. data/ext/libxml/ruby_xml_node.o +0 -0
  158. data/ext/libxml/ruby_xml_parser.c +94 -0
  159. data/ext/libxml/ruby_xml_parser.h +14 -0
  160. data/ext/libxml/ruby_xml_parser.o +0 -0
  161. data/ext/libxml/ruby_xml_parser_context.c +982 -0
  162. data/ext/libxml/ruby_xml_parser_context.h +12 -0
  163. data/ext/libxml/ruby_xml_parser_context.o +0 -0
  164. data/ext/libxml/ruby_xml_parser_options.c +68 -0
  165. data/ext/libxml/ruby_xml_parser_options.h +14 -0
  166. data/ext/libxml/ruby_xml_parser_options.o +0 -0
  167. data/ext/libxml/ruby_xml_reader.c +1002 -0
  168. data/ext/libxml/ruby_xml_reader.h +14 -0
  169. data/ext/libxml/ruby_xml_reader.o +0 -0
  170. data/ext/libxml/ruby_xml_relaxng.c +111 -0
  171. data/ext/libxml/ruby_xml_relaxng.h +10 -0
  172. data/ext/libxml/ruby_xml_relaxng.o +0 -0
  173. data/ext/libxml/ruby_xml_sax2_handler.c +322 -0
  174. data/ext/libxml/ruby_xml_sax2_handler.h +12 -0
  175. data/ext/libxml/ruby_xml_sax2_handler.o +0 -0
  176. data/ext/libxml/ruby_xml_sax_parser.c +137 -0
  177. data/ext/libxml/ruby_xml_sax_parser.h +12 -0
  178. data/ext/libxml/ruby_xml_sax_parser.o +0 -0
  179. data/ext/libxml/ruby_xml_schema.c +159 -0
  180. data/ext/libxml/ruby_xml_schema.h +11 -0
  181. data/ext/libxml/ruby_xml_schema.o +0 -0
  182. data/ext/libxml/ruby_xml_version.h +9 -0
  183. data/ext/libxml/ruby_xml_xinclude.c +18 -0
  184. data/ext/libxml/ruby_xml_xinclude.h +13 -0
  185. data/ext/libxml/ruby_xml_xinclude.o +0 -0
  186. data/ext/libxml/ruby_xml_xpath.c +107 -0
  187. data/ext/libxml/ruby_xml_xpath.h +12 -0
  188. data/ext/libxml/ruby_xml_xpath.o +0 -0
  189. data/ext/libxml/ruby_xml_xpath_context.c +387 -0
  190. data/ext/libxml/ruby_xml_xpath_context.h +11 -0
  191. data/ext/libxml/ruby_xml_xpath_context.o +0 -0
  192. data/ext/libxml/ruby_xml_xpath_expression.c +83 -0
  193. data/ext/libxml/ruby_xml_xpath_expression.h +12 -0
  194. data/ext/libxml/ruby_xml_xpath_expression.o +0 -0
  195. data/ext/libxml/ruby_xml_xpath_object.c +336 -0
  196. data/ext/libxml/ruby_xml_xpath_object.h +19 -0
  197. data/ext/libxml/ruby_xml_xpath_object.o +0 -0
  198. data/ext/libxml/ruby_xml_xpointer.c +101 -0
  199. data/ext/libxml/ruby_xml_xpointer.h +13 -0
  200. data/ext/libxml/ruby_xml_xpointer.o +0 -0
  201. data/ext/mingw/Rakefile +34 -0
  202. data/ext/mingw/build.rake +41 -0
  203. data/ext/vc/libxml_ruby.sln +26 -0
  204. data/lib/libxml.rb +30 -0
  205. data/lib/libxml/attr.rb +111 -0
  206. data/lib/libxml/attr_decl.rb +78 -0
  207. data/lib/libxml/attributes.rb +12 -0
  208. data/lib/libxml/document.rb +190 -0
  209. data/lib/libxml/error.rb +88 -0
  210. data/lib/libxml/hpricot.rb +76 -0
  211. data/lib/libxml/html_parser.rb +94 -0
  212. data/lib/libxml/namespace.rb +60 -0
  213. data/lib/libxml/namespaces.rb +36 -0
  214. data/lib/libxml/node.rb +385 -0
  215. data/lib/libxml/ns.rb +20 -0
  216. data/lib/libxml/parser.rb +365 -0
  217. data/lib/libxml/properties.rb +21 -0
  218. data/lib/libxml/reader.rb +27 -0
  219. data/lib/libxml/sax_callbacks.rb +178 -0
  220. data/lib/libxml/sax_parser.rb +56 -0
  221. data/lib/libxml/tree.rb +27 -0
  222. data/lib/libxml/xpath_object.rb +14 -0
  223. data/lib/xml.rb +14 -0
  224. data/lib/xml/libxml.rb +8 -0
  225. data/setup.rb +1585 -0
  226. data/test/etc_doc_to_s.rb +19 -0
  227. data/test/ets_doc_file.rb +15 -0
  228. data/test/ets_doc_to_s.rb +21 -0
  229. data/test/ets_gpx.rb +26 -0
  230. data/test/ets_node_gc.rb +21 -0
  231. data/test/ets_test.xml +2 -0
  232. data/test/ets_tsr.rb +9 -0
  233. data/test/model/atom.xml +13 -0
  234. data/test/model/bands.xml +5 -0
  235. data/test/model/books.xml +146 -0
  236. data/test/model/merge_bug_data.xml +58 -0
  237. data/test/model/ruby-lang.html +238 -0
  238. data/test/model/rubynet.xml +79 -0
  239. data/test/model/rubynet_project +1 -0
  240. data/test/model/shiporder.rnc +28 -0
  241. data/test/model/shiporder.rng +86 -0
  242. data/test/model/shiporder.xml +23 -0
  243. data/test/model/shiporder.xsd +31 -0
  244. data/test/model/soap.xml +27 -0
  245. data/test/model/xinclude.xml +5 -0
  246. data/test/tc_attr.rb +170 -0
  247. data/test/tc_attr_decl.rb +131 -0
  248. data/test/tc_attributes.rb +133 -0
  249. data/test/tc_deprecated_require.rb +11 -0
  250. data/test/tc_document.rb +113 -0
  251. data/test/tc_document_write.rb +118 -0
  252. data/test/tc_dtd.rb +123 -0
  253. data/test/tc_error.rb +136 -0
  254. data/test/tc_html_parser.rb +138 -0
  255. data/test/tc_namespace.rb +59 -0
  256. data/test/tc_namespaces.rb +174 -0
  257. data/test/tc_node.rb +181 -0
  258. data/test/tc_node_cdata.rb +49 -0
  259. data/test/tc_node_comment.rb +30 -0
  260. data/test/tc_node_copy.rb +40 -0
  261. data/test/tc_node_edit.rb +158 -0
  262. data/test/tc_node_text.rb +69 -0
  263. data/test/tc_node_write.rb +83 -0
  264. data/test/tc_node_xlink.rb +26 -0
  265. data/test/tc_parser.rb +330 -0
  266. data/test/tc_parser_context.rb +186 -0
  267. data/test/tc_properties.rb +36 -0
  268. data/test/tc_reader.rb +284 -0
  269. data/test/tc_relaxng.rb +51 -0
  270. data/test/tc_sax_parser.rb +274 -0
  271. data/test/tc_schema.rb +51 -0
  272. data/test/tc_traversal.rb +220 -0
  273. data/test/tc_xinclude.rb +19 -0
  274. data/test/tc_xml.rb +224 -0
  275. data/test/tc_xpath.rb +193 -0
  276. data/test/tc_xpath_context.rb +78 -0
  277. data/test/tc_xpath_expression.rb +35 -0
  278. data/test/tc_xpointer.rb +72 -0
  279. data/test/test_suite.rb +33 -0
  280. metadata +376 -0
@@ -0,0 +1,13 @@
1
+ /* $Id: ruby_xml_attr.h 666 2008-12-07 00:16:50Z cfis $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ #ifndef __RXML_ATTR_DECL__
6
+ #define __RXML_ATTR_DECL__
7
+
8
+ extern VALUE cXMLAttrDecl;
9
+
10
+ void rxml_init_attr_decl(void);
11
+ VALUE rxml_attr_decl_wrap(xmlAttributePtr xattribute);
12
+ VALUE rxml_attr_decl_value_get(VALUE self);
13
+ #endif
@@ -0,0 +1,277 @@
1
+ /* $Id: rxml_attributes.c 300 2008-07-01 19:14:15Z cfis $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ /*
6
+ * Document-class: LibXML::XML::Attributes
7
+ *
8
+ * Provides access to an element's attributes (XML::Attr).
9
+ *
10
+ * Basic Usage:
11
+ * require 'xml'
12
+ *
13
+ * doc = XML::Document.new(<some_file>)
14
+ * attributes = doc.root.attributes
15
+ *
16
+ * attributes.each do |attribute|
17
+ * ..
18
+ * end
19
+ *
20
+ * attributes['foo'] = 'bar'
21
+ * attribute = attributes.get_attribute['foo']
22
+ * attribute.value == 'foo'
23
+ *
24
+ * To access a namespaced attribute:
25
+ *
26
+ * XLINK_URI = 'http://www.w3.org/1999/xlink'
27
+ *
28
+ * attribute = attributes.get_attribute_ns(XLINK_URI, 'title')
29
+ * attribute.value = 'My title'
30
+ */
31
+
32
+ #include "ruby_libxml.h"
33
+ #include "ruby_xml_attributes.h"
34
+
35
+ VALUE cXMLAttributes;
36
+
37
+ void rxml_attributes_mark(xmlNodePtr xnode)
38
+ {
39
+ rxml_node_mark(xnode);
40
+ }
41
+
42
+ /*
43
+ * Creates a new attributes instance. Not exposed to ruby.
44
+ */
45
+ VALUE rxml_attributes_new(xmlNodePtr xnode)
46
+ {
47
+ return Data_Wrap_Struct(cXMLAttributes, rxml_attributes_mark, NULL, xnode);
48
+ }
49
+
50
+ /*
51
+ * call-seq:
52
+ * attributes.node -> XML::Node
53
+ *
54
+ * Return the node that owns this attributes list.
55
+ *
56
+ * doc.root.attributes.node == doc.root
57
+ */
58
+ VALUE rxml_attributes_node_get(VALUE self)
59
+ {
60
+ xmlNodePtr xnode;
61
+ Data_Get_Struct(self, xmlNode, xnode);
62
+ return rxml_node_wrap(xnode);
63
+ }
64
+
65
+ /*
66
+ * call-seq:
67
+ * attributes.get_attribute("name") -> (XML::Attr | XML::AtrrDecl)
68
+ *
69
+ * Returns the specified attribute. If the attribute does not
70
+ * exist but the document has an associated DTD that defines
71
+ * a default value for the attribute, then a XML::AttrDecl is
72
+ * returned.
73
+ *
74
+ * name: The name of the attribute, not including a namespace.
75
+ *
76
+ * doc.root.attributes.get_attribute("foo")
77
+ */
78
+ static VALUE rxml_attributes_get_attribute(VALUE self, VALUE name)
79
+ {
80
+ xmlNodePtr xnode;
81
+ xmlAttrPtr xattr;
82
+
83
+ name = rb_obj_as_string(name);
84
+
85
+ Data_Get_Struct(self, xmlNode, xnode);
86
+
87
+ xattr = xmlHasProp(xnode, (xmlChar*) StringValuePtr(name));
88
+
89
+ if (!xattr)
90
+ return Qnil;
91
+ else if (xattr->type == XML_ATTRIBUTE_DECL)
92
+ return rxml_attr_decl_wrap((xmlAttributePtr)xattr);
93
+ else
94
+ return rxml_attr_wrap(xattr);
95
+ }
96
+
97
+ /*
98
+ * call-seq:
99
+ * attributes.get_attribute_ns("namespace", "name") -> (XML::Attr | XML::AtrrDecl)
100
+ *
101
+ * Returns the specified attribute. If the attribute does not
102
+ * exist but the document has an associated DTD that defines
103
+ * a default value for the attribute, then a XML::AttrDecl is
104
+ * returned.
105
+ *
106
+ * namespace: The URI of the attribute's namespace.
107
+ * name: The name of the attribute, not including a namespace.
108
+ *
109
+ * doc.root.attributes.get_attribute_ns('http://www.w3.org/1999/xlink', 'href')
110
+ */
111
+ static VALUE rxml_attributes_get_attribute_ns(VALUE self, VALUE namespace,
112
+ VALUE name)
113
+ {
114
+ xmlNodePtr xnode;
115
+ xmlAttrPtr xattr;
116
+
117
+ name = rb_obj_as_string(name);
118
+
119
+ Data_Get_Struct(self, xmlNode, xnode);
120
+
121
+ xattr = xmlHasNsProp(xnode, (xmlChar*) StringValuePtr(name),
122
+ (xmlChar*) StringValuePtr(namespace));
123
+
124
+ if (!xattr)
125
+ return Qnil;
126
+ else if (xattr->type == XML_ATTRIBUTE_DECL)
127
+ return rxml_attr_decl_wrap((xmlAttributePtr)xattr);
128
+ else
129
+ return rxml_attr_wrap(xattr);
130
+ }
131
+
132
+ /*
133
+ * call-seq:
134
+ * attributes["name"] -> String
135
+ *
136
+ * Fetches an attribute value. If you want to access the underlying
137
+ * Attribute itself use get_attribute.
138
+ *
139
+ * name: The name of the attribute, not including any namespaces.
140
+ *
141
+ * doc.root.attributes['att'] -> 'some value'
142
+ */
143
+ VALUE rxml_attributes_attribute_get(VALUE self, VALUE name)
144
+ {
145
+ VALUE xattr = rxml_attributes_get_attribute(self, name);
146
+
147
+ if (NIL_P(xattr))
148
+ return Qnil;
149
+ else
150
+ return rxml_attr_value_get(xattr);
151
+ }
152
+
153
+ /*
154
+ * call-seq:
155
+ * attributes["name"] = "value"
156
+ *
157
+ * Sets an attribute value. If you want to get the Attribute itself,
158
+ * use get_attribute.
159
+ *
160
+ * name: The name of the attribute, not including any namespaces.
161
+ * value: The new value of the namespace.
162
+ *
163
+ * doc.root.attributes['att'] = 'some value'
164
+ */
165
+ VALUE rxml_attributes_attribute_set(VALUE self, VALUE name, VALUE value)
166
+ {
167
+ VALUE xattr = rxml_attributes_get_attribute(self, name);
168
+ if (NIL_P(xattr))
169
+ {
170
+ VALUE args[3];
171
+
172
+ args[0] = rxml_attributes_node_get(self);
173
+ args[1] = name;
174
+ args[2] = value;
175
+
176
+ return rb_class_new_instance(sizeof(args)/sizeof(VALUE), args, cXMLAttr);
177
+ }
178
+ else
179
+ {
180
+ return rxml_attr_value_set(xattr, value);
181
+ }
182
+ }
183
+
184
+ /*
185
+ * call-seq:
186
+ * attributes.each {block} -> XML::Attr
187
+ *
188
+ * Iterates over each attribute.
189
+ *
190
+ * doc.root.attributes.each {|attribute| puts attribute.name}
191
+ */
192
+ static VALUE rxml_attributes_each(VALUE self)
193
+ {
194
+ xmlNodePtr xnode;
195
+ xmlAttrPtr xattr;
196
+ Data_Get_Struct(self, xmlNode, xnode);
197
+
198
+ xattr = xnode->properties;
199
+
200
+ while (xattr)
201
+ {
202
+ /* Get the next attribute while we still can - the user
203
+ may remove the yielded attribute. */
204
+ xmlAttrPtr next = xattr->next;
205
+
206
+ VALUE attr = rxml_attr_wrap(xattr);
207
+ rb_yield(attr);
208
+ xattr = next;
209
+ }
210
+
211
+ return self;
212
+ }
213
+
214
+ /*
215
+ * call-seq:
216
+ * attributes.length -> Integer
217
+ *
218
+ * Returns the number of attributes.
219
+ *
220
+ * doc.root.attributes.length
221
+ */
222
+ static VALUE rxml_attributes_length(VALUE self)
223
+ {
224
+ int length = 0;
225
+ xmlNodePtr xnode;
226
+ xmlAttrPtr xattr;
227
+ Data_Get_Struct(self, xmlNode, xnode);
228
+
229
+ xattr = xnode->properties;
230
+
231
+ while (xattr)
232
+ {
233
+ length++;
234
+ xattr = xattr->next;
235
+ }
236
+
237
+ return INT2NUM(length);
238
+ }
239
+
240
+ /*
241
+ * call-seq:
242
+ * attributes.first -> XML::Attr
243
+ *
244
+ * Returns the first attribute.
245
+ *
246
+ * doc.root.attributes.first
247
+ */
248
+ static VALUE rxml_attributes_first(VALUE self)
249
+ {
250
+ xmlNodePtr xnode;
251
+ Data_Get_Struct(self, xmlNode, xnode);
252
+
253
+ if (xnode->type == XML_ELEMENT_NODE)
254
+ {
255
+ xmlAttrPtr xattr = xnode->properties;
256
+
257
+ if (xattr)
258
+ {
259
+ return rxml_attr_wrap(xattr);
260
+ }
261
+ }
262
+ return Qnil;
263
+ }
264
+
265
+ void rxml_init_attributes(void)
266
+ {
267
+ cXMLAttributes = rb_define_class_under(mXML, "Attributes", rb_cObject);
268
+ rb_include_module(cXMLAttributes, rb_mEnumerable);
269
+ rb_define_method(cXMLAttributes, "node", rxml_attributes_node_get, 0);
270
+ rb_define_method(cXMLAttributes, "get_attribute", rxml_attributes_get_attribute, 1);
271
+ rb_define_method(cXMLAttributes, "get_attribute_ns", rxml_attributes_get_attribute_ns, 2);
272
+ rb_define_method(cXMLAttributes, "[]", rxml_attributes_attribute_get, 1);
273
+ rb_define_method(cXMLAttributes, "[]=", rxml_attributes_attribute_set, 2);
274
+ rb_define_method(cXMLAttributes, "each", rxml_attributes_each, 0);
275
+ rb_define_method(cXMLAttributes, "length", rxml_attributes_length, 0);
276
+ rb_define_method(cXMLAttributes, "first", rxml_attributes_first, 0);
277
+ }
@@ -0,0 +1,17 @@
1
+ /* $Id: rxml_attributes.h 282 2008-07-01 06:44:30Z cfis $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ #ifndef __RXML_ATTRIBUTES__
6
+ #define __RXML_ATTRIBUTES__
7
+
8
+ extern VALUE cXMLAttributesibutes;
9
+
10
+ void rxml_init_attributes(void);
11
+ VALUE rxml_attributes_new(xmlNodePtr xnode);
12
+
13
+ VALUE rxml_attributes_attribute_get(VALUE self, VALUE name);
14
+ VALUE rxml_attributes_attribute_set(VALUE self, VALUE name, VALUE value);
15
+
16
+
17
+ #endif
@@ -0,0 +1,86 @@
1
+ #include "ruby_libxml.h"
2
+ #include <string.h>
3
+ #include <libxml/xmlIO.h>
4
+
5
+ /*
6
+ int xmlRegisterInputCallbacks (xmlInputMatchCallback matchFunc,
7
+ xmlInputOpenCallback openFunc,
8
+ xmlInputReadCallback readFunc,
9
+ xmlInputCloseCallback closeFunc);
10
+
11
+
12
+ int (*xmlInputMatchCallback) (char const *filename);
13
+ void* (*xmlInputOpenCallback) (char const *filename);
14
+ int (*xmlInputReadCallback) (void *context,
15
+ char *buffer,
16
+ int len);
17
+ int (*xmlInputCloseCallback) (void *context);
18
+ */
19
+
20
+ typedef struct deb_doc_context
21
+ {
22
+ char *buffer;
23
+ char *bpos;
24
+ int remaining;
25
+ } deb_doc_context;
26
+
27
+ int deb_Match(char const *filename)
28
+ {
29
+ fprintf(stderr, "deb_Match: %s\n", filename);
30
+ if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "deb://", 6))
31
+ {
32
+ return (1);
33
+ }
34
+ return (0);
35
+ }
36
+
37
+ void* deb_Open(char const *filename)
38
+ {
39
+ deb_doc_context *deb_doc;
40
+ VALUE res;
41
+
42
+ deb_doc = (deb_doc_context*) malloc(sizeof(deb_doc_context));
43
+
44
+ res = rb_funcall(rb_funcall(rb_mKernel, rb_intern("const_get"), 1,
45
+ rb_str_new2("DEBSystem")), rb_intern("document_query"), 1, rb_str_new2(
46
+ filename));
47
+ deb_doc->buffer = strdup(StringValuePtr(res));
48
+ //deb_doc->buffer = strdup("<serepes>serepes</serepes>");
49
+
50
+ deb_doc->bpos = deb_doc->buffer;
51
+ deb_doc->remaining = strlen(deb_doc->buffer);
52
+ return deb_doc;
53
+ }
54
+
55
+ int deb_Read(void *context, char *buffer, int len)
56
+ {
57
+ deb_doc_context *deb_doc;
58
+ int ret_len;
59
+ deb_doc = (deb_doc_context*) context;
60
+
61
+ if (len >= deb_doc->remaining)
62
+ {
63
+ ret_len = deb_doc->remaining;
64
+ }
65
+ else
66
+ {
67
+ ret_len = len;
68
+ }
69
+ deb_doc->remaining -= ret_len;
70
+ strncpy(buffer, deb_doc->bpos, ret_len);
71
+ deb_doc->bpos += ret_len;
72
+
73
+ return ret_len;
74
+ }
75
+
76
+ int deb_Close(void *context)
77
+ {
78
+ free(((deb_doc_context*) context)->buffer);
79
+ free(context);
80
+ return 1;
81
+ }
82
+
83
+ void deb_register_cbg()
84
+ {
85
+ xmlRegisterInputCallbacks(deb_Match, deb_Open, deb_Read, deb_Close);
86
+ }
Binary file
@@ -0,0 +1,1006 @@
1
+ /* $Id: ruby_xml_document.c 854 2009-03-22 04:27:13Z cfis $ */
2
+
3
+ /*
4
+ * Document-class: LibXML::XML::Document
5
+ *
6
+ * The XML::Document class provides a tree based API for working
7
+ * with xml documents. You may directly create a document and
8
+ * manipulate it, or create a document from a data source by
9
+ * using an XML::Parser object.
10
+ *
11
+ * To read a document from a file:
12
+ *
13
+ * doc = XML::Document.file('my_file')
14
+ *
15
+ * To use a parser to read a document:
16
+ *
17
+ * parser = XML::Parser.file('my_file')
18
+ * doc = parser.parse
19
+ *
20
+ * To create a document from scratch:
21
+ *
22
+ * doc = XML::Document.new()
23
+ * doc.root = XML::Node.new('root_node')
24
+ * doc.root << XML::Node.new('elem1')
25
+ * doc.save(filename, :indent => true, :encoding => 'UTF-8')
26
+ *
27
+ * To write a document to a file:
28
+ *
29
+ * doc = XML::Document.new()
30
+ * doc.root = XML::Node.new('root_node')
31
+ * root = doc.root
32
+ *
33
+ * root << elem1 = XML::Node.new('elem1')
34
+ * elem1['attr1'] = 'val1'
35
+ * elem1['attr2'] = 'val2'
36
+ *
37
+ * root << elem2 = XML::Node.new('elem2')
38
+ * elem2['attr1'] = 'val1'
39
+ * elem2['attr2'] = 'val2'
40
+ *
41
+ * root << elem3 = XML::Node.new('elem3')
42
+ * elem3 << elem4 = XML::Node.new('elem4')
43
+ * elem3 << elem5 = XML::Node.new('elem5')
44
+ *
45
+ * elem5 << elem6 = XML::Node.new('elem6')
46
+ * elem6 << 'Content for element 6'
47
+ *
48
+ * elem3['attr'] = 'baz'
49
+ *
50
+ * doc.save(filename, :indent => true, :encoding => 'UTF-8')
51
+ */
52
+
53
+ #include <stdarg.h>
54
+ #include "ruby_libxml.h"
55
+ #include "ruby_xml_document.h"
56
+
57
+ VALUE cXMLDocument;
58
+
59
+
60
+ void rxml_document_free(xmlDocPtr xdoc)
61
+ {
62
+ xdoc->_private = NULL;
63
+ xmlFreeDoc(xdoc);
64
+ }
65
+
66
+ VALUE rxml_document_wrap(xmlDocPtr xdoc)
67
+ {
68
+ VALUE result;
69
+
70
+ // This node is already wrapped
71
+ if (xdoc->_private != NULL)
72
+ {
73
+ result = (VALUE) xdoc->_private;
74
+ }
75
+ else
76
+ {
77
+ result = Data_Wrap_Struct(cXMLDocument, NULL, rxml_document_free, xdoc);
78
+ xdoc->_private = (void*) result;
79
+ }
80
+
81
+ return result;
82
+ }
83
+
84
+ static void LibXML_validity_warning(void * ctxt, const char * msg, va_list ap)
85
+ {
86
+ if (rb_block_given_p())
87
+ {
88
+ char buff[1024];
89
+ snprintf(buff, 1024, msg, ap);
90
+ rb_yield(rb_ary_new3(2, rb_str_new2(buff), Qfalse));
91
+ }
92
+ else
93
+ {
94
+ fprintf(stderr, "warning -- found validity error: ");
95
+ fprintf(stderr, msg, ap);
96
+ }
97
+ }
98
+
99
+ /*
100
+ * call-seq:
101
+ * XML::Document.alloc(xml_version = 1.0) -> document
102
+ *
103
+ * Alocates a new XML::Document, optionally specifying the
104
+ * XML version.
105
+ */
106
+ static VALUE rxml_document_alloc(VALUE klass)
107
+ {
108
+ return Data_Wrap_Struct(klass, NULL, rxml_document_free, NULL);
109
+ }
110
+
111
+ /*
112
+ * call-seq:
113
+ * XML::Document.initialize(xml_version = 1.0) -> document
114
+ *
115
+ * Initializes a new XML::Document, optionally specifying the
116
+ * XML version.
117
+ */
118
+ static VALUE rxml_document_initialize(int argc, VALUE *argv, VALUE self)
119
+ {
120
+ xmlDocPtr xdoc;
121
+ VALUE xmlver;
122
+
123
+ switch (argc)
124
+ {
125
+ case 0:
126
+ xmlver = rb_str_new2("1.0");
127
+ break;
128
+ case 1:
129
+ rb_scan_args(argc, argv, "01", &xmlver);
130
+ break;
131
+ default:
132
+ rb_raise(rb_eArgError, "wrong number of arguments (need 0 or 1)");
133
+ }
134
+
135
+ Check_Type(xmlver, T_STRING);
136
+ xdoc = xmlNewDoc((xmlChar*) StringValuePtr(xmlver));
137
+ xdoc->_private = (void*) self;
138
+ DATA_PTR(self) = xdoc;
139
+
140
+ return self;
141
+ }
142
+
143
+ /*
144
+ * call-seq:
145
+ * document.canonicalize(xpath, mode, inclusive_ns_prefixes, comments) -> String
146
+ *
147
+ * Returns a string containing the canonicalized form of the document, or
148
+ * the subset specified by the xpath argument.
149
+ *
150
+ */
151
+ static VALUE rxml_document_canonicalize(VALUE self, VALUE xpath_expr, VALUE mode, VALUE inclusive_ns_prefixes, VALUE comments) {
152
+ Check_Type(mode, T_FIXNUM);
153
+ Check_Type(comments, T_FIXNUM);
154
+
155
+ xmlDocPtr xdoc;
156
+ xmlXPathObjectPtr xpathObj;
157
+ xmlXPathContextPtr xpathCtx;
158
+ xmlChar *buffer = NULL;
159
+ xmlNodeSetPtr nodes_to_canonize = NULL;
160
+ xmlChar** prefixes = NULL;
161
+
162
+ Data_Get_Struct(self, xmlDoc, xdoc);
163
+
164
+ if(TYPE(xpath_expr) == T_STRING) {
165
+ VALUE expression = rb_check_string_type(xpath_expr);
166
+ xpathCtx = xmlXPathNewContext(xdoc);
167
+ xpathCtx->node = xmlDocGetRootElement(xdoc);
168
+ // Load document namespaces into the xpath context
169
+ xmlNsPtr *xnsArr = xmlGetNsList(xdoc, xpathCtx->node);
170
+ if(xnsArr) {
171
+ xmlNsPtr xns = *xnsArr;
172
+ while(xns) {
173
+ if (xns->prefix)
174
+ xmlXPathRegisterNs(xpathCtx, xns->prefix, xns->href);
175
+ xns = xns->next;
176
+ }
177
+ xmlFree(xnsArr);
178
+ }
179
+ xpathObj = xmlXPathEval((xmlChar*) StringValueCStr(expression), xpathCtx);
180
+ if(xpathObj == NULL) {
181
+ rxml_raise(xmlGetLastError());
182
+ }
183
+ nodes_to_canonize = xpathObj->nodesetval;
184
+ if(nodes_to_canonize == NULL || nodes_to_canonize->nodeNr == 0) {
185
+ //xpath didn't match anything, do nothing
186
+ return Qnil;
187
+ }
188
+ }
189
+ if(!NIL_P(inclusive_ns_prefixes)) {
190
+ int i;
191
+ struct RArray *ns_prefixes_array;
192
+ ns_prefixes_array = RARRAY(inclusive_ns_prefixes);
193
+ prefixes = (xmlChar**)malloc(sizeof(xmlChar**) * ns_prefixes_array->len + 1);
194
+ for(i=0;i<ns_prefixes_array->len;i++) {
195
+ VALUE prefix = ns_prefixes_array->ptr[i];
196
+ prefixes[i] = (xmlChar*)StringValueCStr(prefix);
197
+ }
198
+ prefixes[ns_prefixes_array->len]=NULL;
199
+ }
200
+
201
+ int length = xmlC14NDocDumpMemory(xdoc,nodes_to_canonize,FIX2INT(mode),prefixes,FIX2INT(comments), &buffer);
202
+ free(prefixes);
203
+ VALUE result = rb_str_new((const char*)buffer, length);
204
+ if(nodes_to_canonize) {
205
+ xmlXPathFreeContext(xpathCtx);
206
+ xmlXPathFreeObject(xpathObj);
207
+ } xmlFree(buffer);
208
+ return result;
209
+ }
210
+
211
+
212
+ /*
213
+ * call-seq:
214
+ * document.compression -> num
215
+ *
216
+ * Obtain this document's compression mode identifier.
217
+ */
218
+ static VALUE rxml_document_compression_get(VALUE self)
219
+ {
220
+ #ifdef HAVE_ZLIB_H
221
+ xmlDocPtr xdoc;
222
+
223
+ int compmode;
224
+ Data_Get_Struct(self, xmlDoc, xdoc);
225
+
226
+ compmode = xmlGetDocCompressMode(xdoc);
227
+ if (compmode == -1)
228
+ return(Qnil);
229
+ else
230
+ return(INT2NUM(compmode));
231
+ #else
232
+ rb_warn("libxml not compiled with zlib support");
233
+ return (Qfalse);
234
+ #endif
235
+ }
236
+
237
+ /*
238
+ * call-seq:
239
+ * document.compression = num
240
+ *
241
+ * Set this document's compression mode.
242
+ */
243
+ static VALUE rxml_document_compression_set(VALUE self, VALUE num)
244
+ {
245
+ #ifdef HAVE_ZLIB_H
246
+ xmlDocPtr xdoc;
247
+
248
+ int compmode;
249
+ Check_Type(num, T_FIXNUM);
250
+ Data_Get_Struct(self, xmlDoc, xdoc);
251
+
252
+ if (xdoc == NULL)
253
+ {
254
+ return(Qnil);
255
+ }
256
+ else
257
+ {
258
+ xmlSetDocCompressMode(xdoc, NUM2INT(num));
259
+
260
+ compmode = xmlGetDocCompressMode(xdoc);
261
+ if (compmode == -1)
262
+ return(Qnil);
263
+ else
264
+ return(INT2NUM(compmode));
265
+ }
266
+ #else
267
+ rb_warn("libxml compiled without zlib support");
268
+ return (Qfalse);
269
+ #endif
270
+ }
271
+
272
+ /*
273
+ * call-seq:
274
+ * document.compression? -> (true|false)
275
+ *
276
+ * Determine whether this document is compressed.
277
+ */
278
+ static VALUE rxml_document_compression_q(VALUE self)
279
+ {
280
+ #ifdef HAVE_ZLIB_H
281
+ xmlDocPtr xdoc;
282
+
283
+ Data_Get_Struct(self, xmlDoc, xdoc);
284
+
285
+ if (xdoc->compression != -1)
286
+ return(Qtrue);
287
+ else
288
+ return(Qfalse);
289
+ #else
290
+ rb_warn("libxml compiled without zlib support");
291
+ return (Qfalse);
292
+ #endif
293
+ }
294
+
295
+ /*
296
+ * call-seq:
297
+ * document.child -> node
298
+ *
299
+ * Get this document's child node.
300
+ */
301
+ static VALUE rxml_document_child_get(VALUE self)
302
+ {
303
+ xmlDocPtr xdoc;
304
+ Data_Get_Struct(self, xmlDoc, xdoc);
305
+
306
+ if (xdoc->children == NULL)
307
+ return (Qnil);
308
+
309
+ return rxml_node_wrap(xdoc->children);
310
+ }
311
+
312
+ /*
313
+ * call-seq:
314
+ * document.child? -> (true|false)
315
+ *
316
+ * Determine whether this document has a child node.
317
+ */
318
+ static VALUE rxml_document_child_q(VALUE self)
319
+ {
320
+ xmlDocPtr xdoc;
321
+ Data_Get_Struct(self, xmlDoc, xdoc);
322
+
323
+ if (xdoc->children == NULL)
324
+ return (Qfalse);
325
+ else
326
+ return (Qtrue);
327
+ }
328
+
329
+
330
+ /*
331
+ * call-seq:
332
+ * node.debug -> true|false
333
+ *
334
+ * Print libxml debugging information to stdout.
335
+ * Requires that libxml was compiled with debugging enabled.
336
+ */
337
+ static VALUE rxml_document_debug(VALUE self)
338
+ {
339
+ #ifdef LIBXML_DEBUG_ENABLED
340
+ xmlDocPtr xdoc;
341
+ Data_Get_Struct(self, xmlDoc, xdoc);
342
+ xmlDebugDumpDocument(NULL, xdoc);
343
+ return Qtrue;
344
+ #else
345
+ rb_warn("libxml was compiled without debugging support.")
346
+ return Qfalse;
347
+ #endif
348
+ }
349
+
350
+ /*
351
+ * call-seq:
352
+ * document.encoding -> XML::Encoding::UTF_8
353
+ *
354
+ * Obtain the encoding specified by this document.
355
+ */
356
+ static VALUE rxml_document_encoding_get(VALUE self)
357
+ {
358
+ xmlDocPtr xdoc;
359
+ const char *xencoding;
360
+ Data_Get_Struct(self, xmlDoc, xdoc);
361
+
362
+ xencoding = (const char*)xdoc->encoding;
363
+ return INT2NUM(xmlParseCharEncoding(xencoding));
364
+ }
365
+
366
+ /*
367
+ * call-seq:
368
+ * document.encoding = XML::Encoding::UTF_8
369
+ *
370
+ * Set the encoding for this document.
371
+ */
372
+ static VALUE rxml_document_encoding_set(VALUE self, VALUE encoding)
373
+ {
374
+ xmlDocPtr xdoc;
375
+ const char* xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(encoding));
376
+
377
+ Data_Get_Struct(self, xmlDoc, xdoc);
378
+
379
+ if (xdoc->encoding != NULL)
380
+ xmlFree((xmlChar *) xdoc->encoding);
381
+
382
+ xdoc->encoding = xmlStrdup((xmlChar *)xencoding);
383
+ return self;
384
+ }
385
+
386
+ /*
387
+ * call-seq:
388
+ * document.import(node) -> XML::Node
389
+ *
390
+ * Creates a copy of the node that can be inserted into the
391
+ * current document.
392
+ */
393
+ static VALUE rxml_document_import(VALUE self, VALUE node)
394
+ {
395
+ xmlDocPtr xdoc;
396
+ xmlNodePtr xnode, xresult;
397
+
398
+ Data_Get_Struct(self, xmlDoc, xdoc);
399
+ Data_Get_Struct(node, xmlNode, xnode);
400
+
401
+ xresult = xmlDocCopyNode(xnode, xdoc, 1);
402
+
403
+ if (xresult == NULL)
404
+ rxml_raise(&xmlLastError);
405
+
406
+ return rxml_node_wrap(xresult);
407
+ }
408
+
409
+ /*
410
+ * call-seq:
411
+ * document.last -> node
412
+ *
413
+ * Obtain the last node.
414
+ */
415
+ static VALUE rxml_document_last_get(VALUE self)
416
+ {
417
+ xmlDocPtr xdoc;
418
+
419
+ Data_Get_Struct(self, xmlDoc, xdoc);
420
+
421
+ if (xdoc->last == NULL)
422
+ return (Qnil);
423
+
424
+ return rxml_node_wrap(xdoc->last);
425
+ }
426
+
427
+ /*
428
+ * call-seq:
429
+ * document.last? -> (true|false)
430
+ *
431
+ * Determine whether there is a last node.
432
+ */
433
+ static VALUE rxml_document_last_q(VALUE self)
434
+ {
435
+ xmlDocPtr xdoc;
436
+
437
+ Data_Get_Struct(self, xmlDoc, xdoc);
438
+
439
+ if (xdoc->last == NULL)
440
+ return (Qfalse);
441
+ else
442
+ return (Qtrue);
443
+ }
444
+
445
+ /*
446
+ * call-seq:
447
+ * document.next -> node
448
+ *
449
+ * Obtain the next node.
450
+ */
451
+ static VALUE rxml_document_next_get(VALUE self)
452
+ {
453
+ xmlDocPtr xdoc;
454
+
455
+ Data_Get_Struct(self, xmlDoc, xdoc);
456
+
457
+ if (xdoc->next == NULL)
458
+ return (Qnil);
459
+
460
+ return rxml_node_wrap(xdoc->next);
461
+ }
462
+
463
+ /*
464
+ * call-seq:
465
+ * document.next? -> (true|false)
466
+ *
467
+ * Determine whether there is a next node.
468
+ */
469
+ static VALUE rxml_document_next_q(VALUE self)
470
+ {
471
+ xmlDocPtr xdoc;
472
+
473
+ Data_Get_Struct(self, xmlDoc, xdoc);
474
+
475
+ if (xdoc->next == NULL)
476
+ return (Qfalse);
477
+ else
478
+ return (Qtrue);
479
+ }
480
+
481
+ /*
482
+ * call-seq:
483
+ * node.type -> num
484
+ *
485
+ * Obtain this node's type identifier.
486
+ */
487
+ static VALUE rxml_document_node_type(VALUE self)
488
+ {
489
+ xmlNodePtr xnode;
490
+ Data_Get_Struct(self, xmlNode, xnode);
491
+ return (INT2NUM(xnode->type));
492
+ }
493
+
494
+ /*
495
+ * call-seq:
496
+ * document.parent -> node
497
+ *
498
+ * Obtain the parent node.
499
+ */
500
+ static VALUE rxml_document_parent_get(VALUE self)
501
+ {
502
+ xmlDocPtr xdoc;
503
+
504
+ Data_Get_Struct(self, xmlDoc, xdoc);
505
+
506
+ if (xdoc->parent == NULL)
507
+ return (Qnil);
508
+
509
+ return rxml_node_wrap(xdoc->parent);
510
+ }
511
+
512
+ /*
513
+ * call-seq:
514
+ * document.parent? -> (true|false)
515
+ *
516
+ * Determine whether there is a parent node.
517
+ */
518
+ static VALUE rxml_document_parent_q(VALUE self)
519
+ {
520
+ xmlDocPtr xdoc;
521
+
522
+ Data_Get_Struct(self, xmlDoc, xdoc);
523
+
524
+ if (xdoc->parent == NULL)
525
+ return (Qfalse);
526
+ else
527
+ return (Qtrue);
528
+ }
529
+
530
+ /*
531
+ * call-seq:
532
+ * document.prev -> node
533
+ *
534
+ * Obtain the previous node.
535
+ */
536
+ static VALUE rxml_document_prev_get(VALUE self)
537
+ {
538
+ xmlDocPtr xdoc;
539
+
540
+ Data_Get_Struct(self, xmlDoc, xdoc);
541
+
542
+ if (xdoc->prev == NULL)
543
+ return (Qnil);
544
+
545
+ return rxml_node_wrap(xdoc->prev);
546
+ }
547
+
548
+ /*
549
+ * call-seq:
550
+ * document.prev? -> (true|false)
551
+ *
552
+ * Determine whether there is a previous node.
553
+ */
554
+ static VALUE rxml_document_prev_q(VALUE self)
555
+ {
556
+ xmlDocPtr xdoc;
557
+
558
+ Data_Get_Struct(self, xmlDoc, xdoc);
559
+
560
+ if (xdoc->prev == NULL)
561
+ return (Qfalse);
562
+ else
563
+ return (Qtrue);
564
+ }
565
+
566
+ /*
567
+ * call-seq:
568
+ * document.root -> node
569
+ *
570
+ * Obtain the root node.
571
+ */
572
+ static VALUE rxml_document_root_get(VALUE self)
573
+ {
574
+ xmlDocPtr xdoc;
575
+
576
+ xmlNodePtr root;
577
+
578
+ Data_Get_Struct(self, xmlDoc, xdoc);
579
+ root = xmlDocGetRootElement(xdoc);
580
+
581
+ if (root == NULL)
582
+ return (Qnil);
583
+
584
+ return rxml_node_wrap(root);
585
+ }
586
+
587
+ /*
588
+ * call-seq:
589
+ * document.root = node
590
+ *
591
+ * Set the root node.
592
+ */
593
+ static VALUE rxml_document_root_set(VALUE self, VALUE node)
594
+ {
595
+ xmlDocPtr xdoc;
596
+ xmlNodePtr xroot, xnode;
597
+
598
+ if (rb_obj_is_kind_of(node, cXMLNode) == Qfalse)
599
+ rb_raise(rb_eTypeError, "must pass an XML::Node type object");
600
+
601
+ Data_Get_Struct(self, xmlDoc, xdoc);
602
+ Data_Get_Struct(node, xmlNode, xnode);
603
+
604
+ xroot = xmlDocSetRootElement(xdoc, xnode);
605
+ return node;
606
+ }
607
+
608
+ /*
609
+ * call-seq:
610
+ * document.save(filename) -> int
611
+ * document.save(filename, :indent => true, :encoding => 'UTF-8') -> int
612
+ *
613
+ * Saves a document to a file. You may provide an optional hash table
614
+ * to control how the string is generated. Valid options are:
615
+ *
616
+ * :indent - Specifies if the string should be indented. The default value
617
+ * is true. Note that indentation is only added if both :indent is
618
+ * true and XML.indent_tree_output is true. If :indent is set to false,
619
+ * then both indentation and line feeds are removed from the result.
620
+ *
621
+ * :encoding - Specifies the output encoding of the string. It
622
+ * defaults to the original encoding of the document (see
623
+ * #encoding. To override the orginal encoding, use one of the
624
+ * XML::Encoding encoding constants. */
625
+ static VALUE rxml_document_save(int argc, VALUE *argv, VALUE self)
626
+ {
627
+ VALUE options = Qnil;
628
+ VALUE filename = Qnil;
629
+ xmlDocPtr xdoc;
630
+ int indent = 1;
631
+ const char *xfilename;
632
+ const char *xencoding;
633
+ int length;
634
+
635
+ rb_scan_args(argc, argv, "11", &filename, &options);
636
+
637
+ Check_Type(filename, T_STRING);
638
+ xfilename = StringValuePtr(filename);
639
+
640
+ Data_Get_Struct(self, xmlDoc, xdoc);
641
+ xencoding = xdoc->encoding;
642
+
643
+ if (!NIL_P(options))
644
+ {
645
+ VALUE rencoding, rindent;
646
+ Check_Type(options, T_HASH);
647
+ rencoding = rb_hash_aref(options, ID2SYM(rb_intern("encoding")));
648
+ rindent = rb_hash_aref(options, ID2SYM(rb_intern("indent")));
649
+
650
+ if (rindent == Qfalse)
651
+ indent = 0;
652
+
653
+ if (rencoding != Qnil)
654
+ {
655
+ xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(rencoding));
656
+ if (!xencoding)
657
+ rb_raise(rb_eArgError, "Unknown encoding value: %d", NUM2INT(rencoding));
658
+ }
659
+ }
660
+
661
+ length = xmlSaveFormatFileEnc(xfilename, xdoc, xencoding, indent);
662
+
663
+ if (length == -1)
664
+ rxml_raise(&xmlLastError);
665
+
666
+ return (INT2NUM(length));
667
+ }
668
+
669
+ /*
670
+ * call-seq:
671
+ * document.standalone? -> (true|false)
672
+ *
673
+ * Determine whether this is a standalone document.
674
+ */
675
+ static VALUE rxml_document_standalone_q(VALUE self)
676
+ {
677
+ xmlDocPtr xdoc;
678
+
679
+ Data_Get_Struct(self, xmlDoc, xdoc);
680
+ if (xdoc->standalone)
681
+ return (Qtrue);
682
+ else
683
+ return (Qfalse);
684
+ }
685
+
686
+ /*
687
+ * call-seq:
688
+ * document.to_s -> "string"
689
+ * document.to_s(:indent => true, :encoding => 'UTF-8') -> "string"
690
+ *
691
+ * Converts a document, and all of its children, to a string representation.
692
+ * You may provide an optional hash table to control how the string is
693
+ * generated. Valid options are:
694
+ *
695
+ * :indent - Specifies if the string should be indented. The default value
696
+ * is true. Note that indentation is only added if both :indent is
697
+ * true and XML.indent_tree_output is true. If :indent is set to false,
698
+ * then both indentation and line feeds are removed from the result.
699
+ *
700
+ * :encoding - Specifies the output encoding of the string. It
701
+ * defaults to XML::Encoding::UTF8. To change it, use one of the
702
+ * XML::Encoding encoding constants. */
703
+ static VALUE rxml_document_to_s(int argc, VALUE *argv, VALUE self)
704
+ {
705
+ VALUE result;
706
+ VALUE options = Qnil;
707
+ xmlDocPtr xdoc;
708
+ int indent = 1;
709
+ const char *xencoding = "UTF-8";
710
+ xmlChar *buffer;
711
+ int length;
712
+
713
+ rb_scan_args(argc, argv, "01", &options);
714
+
715
+ if (!NIL_P(options))
716
+ {
717
+ VALUE rencoding, rindent;
718
+ Check_Type(options, T_HASH);
719
+ rencoding = rb_hash_aref(options, ID2SYM(rb_intern("encoding")));
720
+ rindent = rb_hash_aref(options, ID2SYM(rb_intern("indent")));
721
+
722
+ if (rindent == Qfalse)
723
+ indent = 0;
724
+
725
+ if (rencoding != Qnil)
726
+ {
727
+ xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(rencoding));
728
+ if (!xencoding)
729
+ rb_raise(rb_eArgError, "Unknown encoding value: %d", NUM2INT(rencoding));
730
+ }
731
+ }
732
+
733
+ Data_Get_Struct(self, xmlDoc, xdoc);
734
+ xmlDocDumpFormatMemoryEnc(xdoc, &buffer, &length, xencoding, indent);
735
+
736
+ result = rb_str_new((const char*) buffer, length);
737
+ xmlFree(buffer);
738
+ return result;
739
+ }
740
+
741
+ /*
742
+ * call-seq:
743
+ * document.url -> "url"
744
+ *
745
+ * Obtain this document's source URL, if any.
746
+ */
747
+ static VALUE rxml_document_url_get(VALUE self)
748
+ {
749
+ xmlDocPtr xdoc;
750
+
751
+ Data_Get_Struct(self, xmlDoc, xdoc);
752
+ if (xdoc->URL == NULL)
753
+ return (Qnil);
754
+ else
755
+ return (rb_str_new2((const char*) xdoc->URL));
756
+ }
757
+
758
+ /*
759
+ * call-seq:
760
+ * document.version -> "version"
761
+ *
762
+ * Obtain the XML version specified by this document.
763
+ */
764
+ static VALUE rxml_document_version_get(VALUE self)
765
+ {
766
+ xmlDocPtr xdoc;
767
+
768
+ Data_Get_Struct(self, xmlDoc, xdoc);
769
+ if (xdoc->version == NULL)
770
+ return (Qnil);
771
+ else
772
+ return (rb_str_new2((const char*) xdoc->version));
773
+ }
774
+
775
+ /*
776
+ * call-seq:
777
+ * document.xhtml? -> (true|false)
778
+ *
779
+ * Determine whether this is an XHTML document.
780
+ */
781
+ static VALUE rxml_document_xhtml_q(VALUE self)
782
+ {
783
+ xmlDocPtr xdoc;
784
+ xmlDtdPtr xdtd;
785
+ Data_Get_Struct(self, xmlDoc, xdoc);
786
+ xdtd = xmlGetIntSubset(xdoc);
787
+ if (xdtd != NULL && xmlIsXHTML(xdtd->SystemID, xdtd->ExternalID) > 0)
788
+ return (Qtrue);
789
+ else
790
+ return (Qfalse);
791
+ }
792
+
793
+ /*
794
+ * call-seq:
795
+ * document.xinclude -> num
796
+ *
797
+ * Process xinclude directives in this document.
798
+ */
799
+ static VALUE rxml_document_xinclude(VALUE self)
800
+ {
801
+ #ifdef LIBXML_XINCLUDE_ENABLED
802
+ xmlDocPtr xdoc;
803
+
804
+ int ret;
805
+
806
+ Data_Get_Struct(self, xmlDoc, xdoc);
807
+ ret = xmlXIncludeProcess(xdoc);
808
+ if (ret >= 0)
809
+ {
810
+ return(INT2NUM(ret));
811
+ }
812
+ else
813
+ {
814
+ rxml_raise(&xmlLastError);
815
+ return Qnil;
816
+ }
817
+ #else
818
+ rb_warn(
819
+ "libxml was compiled without XInclude support. Please recompile libxml and ruby-libxml");
820
+ return (Qfalse);
821
+ #endif
822
+ }
823
+
824
+ void LibXML_validity_error(void * ctxt, const char * msg, va_list ap)
825
+ {
826
+ if (rb_block_given_p())
827
+ {
828
+ char buff[1024];
829
+ snprintf(buff, 1024, msg, ap);
830
+ rb_yield(rb_ary_new3(2, rb_str_new2(buff), Qtrue));
831
+ }
832
+ else
833
+ {
834
+ fprintf(stderr, "error -- found validity error: ");
835
+ fprintf(stderr, msg, ap);
836
+ }
837
+ }
838
+
839
+ /*
840
+ * call-seq:
841
+ * document.order_elements!
842
+ *
843
+ * Call this routine to speed up XPath computation on static documents.
844
+ * This stamps all the element nodes with the document order.
845
+ */
846
+ static VALUE rxml_document_order_elements(VALUE self)
847
+ {
848
+ xmlDocPtr xdoc;
849
+
850
+ Data_Get_Struct(self, xmlDoc, xdoc);
851
+ return LONG2FIX(xmlXPathOrderDocElems(xdoc));
852
+ }
853
+
854
+ /*
855
+ * call-seq:
856
+ * document.validate_schema(schema) -> (true|false)
857
+ *
858
+ * Validate this document against the specified XML::Schema.
859
+ *
860
+ * If a block is provided it is used as an error handler for validaten errors.
861
+ * The block is called with two argument, the message and a flag indication
862
+ * if the message is an error (true) or a warning (false).
863
+ */
864
+ static VALUE rxml_document_validate_schema(VALUE self, VALUE schema)
865
+ {
866
+ xmlSchemaValidCtxtPtr vptr;
867
+ xmlDocPtr xdoc;
868
+ xmlSchemaPtr xschema;
869
+ int is_invalid;
870
+
871
+ Data_Get_Struct(self, xmlDoc, xdoc);
872
+ Data_Get_Struct(schema, xmlSchema, xschema);
873
+
874
+ vptr = xmlSchemaNewValidCtxt(xschema);
875
+
876
+ xmlSchemaSetValidErrors(vptr,
877
+ (xmlSchemaValidityErrorFunc) LibXML_validity_error,
878
+ (xmlSchemaValidityWarningFunc) LibXML_validity_warning, NULL);
879
+
880
+ is_invalid = xmlSchemaValidateDoc(vptr, xdoc);
881
+ xmlSchemaFreeValidCtxt(vptr);
882
+ if (is_invalid)
883
+ {
884
+ rxml_raise(&xmlLastError);
885
+ return Qfalse;
886
+ }
887
+ else
888
+ {
889
+ return Qtrue;
890
+ }
891
+ }
892
+
893
+ /*
894
+ * call-seq:
895
+ * document.validate_schema(relaxng) -> (true|false)
896
+ *
897
+ * Validate this document against the specified XML::RelaxNG.
898
+ *
899
+ * If a block is provided it is used as an error handler for validaten errors.
900
+ * The block is called with two argument, the message and a flag indication
901
+ * if the message is an error (true) or a warning (false).
902
+ */
903
+ static VALUE rxml_document_validate_relaxng(VALUE self, VALUE relaxng)
904
+ {
905
+ xmlRelaxNGValidCtxtPtr vptr;
906
+ xmlDocPtr xdoc;
907
+ xmlRelaxNGPtr xrelaxng;
908
+ int is_invalid;
909
+
910
+ Data_Get_Struct(self, xmlDoc, xdoc);
911
+ Data_Get_Struct(relaxng, xmlRelaxNG, xrelaxng);
912
+
913
+ vptr = xmlRelaxNGNewValidCtxt(xrelaxng);
914
+
915
+ xmlRelaxNGSetValidErrors(vptr,
916
+ (xmlRelaxNGValidityErrorFunc) LibXML_validity_error,
917
+ (xmlRelaxNGValidityWarningFunc) LibXML_validity_warning, NULL);
918
+
919
+ is_invalid = xmlRelaxNGValidateDoc(vptr, xdoc);
920
+ xmlRelaxNGFreeValidCtxt(vptr);
921
+ if (is_invalid)
922
+ {
923
+ rxml_raise(&xmlLastError);
924
+ return Qfalse;
925
+ }
926
+ else
927
+ {
928
+ return Qtrue;
929
+ }
930
+ }
931
+
932
+ /*
933
+ * call-seq:
934
+ * document.validate(dtd) -> (true|false)
935
+ *
936
+ * Validate this document against the specified XML::DTD.
937
+ */
938
+ static VALUE rxml_document_validate_dtd(VALUE self, VALUE dtd)
939
+ {
940
+ VALUE error = Qnil;
941
+ xmlValidCtxt ctxt;
942
+ xmlDocPtr xdoc;
943
+ xmlDtdPtr xdtd;
944
+
945
+ Data_Get_Struct(self, xmlDoc, xdoc);
946
+ Data_Get_Struct(dtd, xmlDtd, xdtd);
947
+
948
+ ctxt.userData = &error;
949
+ ctxt.error = (xmlValidityErrorFunc) LibXML_validity_error;
950
+ ctxt.warning = (xmlValidityWarningFunc) LibXML_validity_warning;
951
+
952
+ ctxt.nodeNr = 0;
953
+ ctxt.nodeTab = NULL;
954
+ ctxt.vstateNr = 0;
955
+ ctxt.vstateTab = NULL;
956
+
957
+ if (xmlValidateDtd(&ctxt, xdoc, xdtd))
958
+ {
959
+ return (Qtrue);
960
+ }
961
+ else
962
+ {
963
+ rxml_raise(&xmlLastError);
964
+ return Qfalse;
965
+ }
966
+ }
967
+
968
+ void rxml_init_document(void)
969
+ {
970
+ cXMLDocument = rb_define_class_under(mXML, "Document", rb_cObject);
971
+ rb_define_alloc_func(cXMLDocument, rxml_document_alloc);
972
+
973
+ rb_define_method(cXMLDocument, "initialize", rxml_document_initialize, -1);
974
+ rb_define_method(cXMLDocument, "child", rxml_document_child_get, 0);
975
+ rb_define_method(cXMLDocument, "child?", rxml_document_child_q, 0);
976
+ rb_define_method(cXMLDocument, "compression", rxml_document_compression_get, 0);
977
+ rb_define_method(cXMLDocument, "compression=", rxml_document_compression_set, 1);
978
+ rb_define_method(cXMLDocument, "compression?", rxml_document_compression_q, 0);
979
+ rb_define_method(cXMLDocument, "debug", rxml_document_debug, 0);
980
+ rb_define_method(cXMLDocument, "encoding", rxml_document_encoding_get, 0);
981
+ rb_define_method(cXMLDocument, "encoding=", rxml_document_encoding_set, 1);
982
+ rb_define_method(cXMLDocument, "import", rxml_document_import, 1);
983
+ rb_define_method(cXMLDocument, "last", rxml_document_last_get, 0);
984
+ rb_define_method(cXMLDocument, "last?", rxml_document_last_q, 0);
985
+ rb_define_method(cXMLDocument, "next", rxml_document_next_get, 0);
986
+ rb_define_method(cXMLDocument, "next?", rxml_document_next_q, 0);
987
+ rb_define_method(cXMLDocument, "node_type", rxml_document_node_type, 0);
988
+ rb_define_method(cXMLDocument, "order_elements!", rxml_document_order_elements, 0);
989
+ rb_define_method(cXMLDocument, "parent", rxml_document_parent_get, 0);
990
+ rb_define_method(cXMLDocument, "parent?", rxml_document_parent_q, 0);
991
+ rb_define_method(cXMLDocument, "prev", rxml_document_prev_get, 0);
992
+ rb_define_method(cXMLDocument, "prev?", rxml_document_prev_q, 0);
993
+ rb_define_method(cXMLDocument, "root", rxml_document_root_get, 0);
994
+ rb_define_method(cXMLDocument, "root=", rxml_document_root_set, 1);
995
+ rb_define_method(cXMLDocument, "save", rxml_document_save, -1);
996
+ rb_define_method(cXMLDocument, "standalone?", rxml_document_standalone_q, 0);
997
+ rb_define_method(cXMLDocument, "to_s", rxml_document_to_s, -1);
998
+ rb_define_method(cXMLDocument, "url", rxml_document_url_get, 0);
999
+ rb_define_method(cXMLDocument, "version", rxml_document_version_get, 0);
1000
+ rb_define_method(cXMLDocument, "xhtml?", rxml_document_xhtml_q, 0);
1001
+ rb_define_method(cXMLDocument, "xinclude", rxml_document_xinclude, 0);
1002
+ rb_define_method(cXMLDocument, "validate", rxml_document_validate_dtd, 1);
1003
+ rb_define_method(cXMLDocument, "validate_schema", rxml_document_validate_schema, 1);
1004
+ rb_define_method(cXMLDocument, "validate_relaxng", rxml_document_validate_relaxng, 1);
1005
+ rb_define_method(cXMLDocument, "canonicalize", rxml_document_canonicalize, 4);
1006
+ }