libxml-ruby 0.9.8-x86-mswin32-60 → 0.9.9-x86-mswin32-60

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 (98) hide show
  1. data/CHANGES +41 -1
  2. data/LICENSE +3 -4
  3. data/README +37 -24
  4. data/Rakefile +2 -2
  5. data/ext/libxml/extconf.rb +31 -12
  6. data/ext/libxml/libxml.c +56 -858
  7. data/ext/libxml/ruby_libxml.h +93 -96
  8. data/ext/libxml/ruby_xml.c +855 -0
  9. data/ext/libxml/ruby_xml.h +9 -0
  10. data/ext/libxml/ruby_xml_attr.c +3 -9
  11. data/ext/libxml/ruby_xml_attr.h +2 -2
  12. data/ext/libxml/ruby_xml_attr_decl.c +2 -8
  13. data/ext/libxml/ruby_xml_attr_decl.h +1 -1
  14. data/ext/libxml/ruby_xml_attributes.c +6 -8
  15. data/ext/libxml/ruby_xml_attributes.h +1 -1
  16. data/ext/libxml/ruby_xml_document.c +915 -895
  17. data/ext/libxml/ruby_xml_document.h +2 -2
  18. data/ext/libxml/ruby_xml_dtd.c +257 -136
  19. data/ext/libxml/ruby_xml_dtd.h +1 -1
  20. data/ext/libxml/ruby_xml_encoding.c +55 -37
  21. data/ext/libxml/ruby_xml_encoding.h +1 -1
  22. data/ext/libxml/ruby_xml_error.c +526 -1058
  23. data/ext/libxml/ruby_xml_error.h +1 -1
  24. data/ext/libxml/ruby_xml_html_parser.c +2 -8
  25. data/ext/libxml/ruby_xml_html_parser.h +2 -2
  26. data/ext/libxml/ruby_xml_html_parser_context.c +175 -145
  27. data/ext/libxml/ruby_xml_html_parser_context.h +1 -1
  28. data/ext/libxml/ruby_xml_html_parser_options.c +12 -20
  29. data/ext/libxml/ruby_xml_html_parser_options.h +1 -1
  30. data/ext/libxml/ruby_xml_input_cbg.c +2 -8
  31. data/ext/libxml/ruby_xml_input_cbg.h +1 -1
  32. data/ext/libxml/ruby_xml_namespace.c +2 -8
  33. data/ext/libxml/ruby_xml_namespace.h +2 -2
  34. data/ext/libxml/ruby_xml_namespaces.c +1 -9
  35. data/ext/libxml/ruby_xml_namespaces.h +1 -1
  36. data/ext/libxml/ruby_xml_node.c +182 -121
  37. data/ext/libxml/ruby_xml_node.h +2 -2
  38. data/ext/libxml/ruby_xml_parser.c +2 -8
  39. data/ext/libxml/ruby_xml_parser.h +2 -2
  40. data/ext/libxml/ruby_xml_parser_context.c +952 -901
  41. data/ext/libxml/ruby_xml_parser_context.h +2 -2
  42. data/ext/libxml/ruby_xml_parser_options.c +2 -9
  43. data/ext/libxml/ruby_xml_parser_options.h +1 -1
  44. data/ext/libxml/ruby_xml_reader.c +1002 -993
  45. data/ext/libxml/ruby_xml_reader.h +1 -1
  46. data/ext/libxml/ruby_xml_relaxng.c +1 -7
  47. data/ext/libxml/ruby_xml_relaxng.h +1 -1
  48. data/ext/libxml/ruby_xml_sax2_handler.c +2 -2
  49. data/ext/libxml/ruby_xml_sax2_handler.h +1 -1
  50. data/ext/libxml/ruby_xml_sax_parser.c +2 -8
  51. data/ext/libxml/ruby_xml_sax_parser.h +2 -2
  52. data/ext/libxml/ruby_xml_schema.c +1 -7
  53. data/ext/libxml/ruby_xml_schema.h +1 -1
  54. data/ext/libxml/{version.h → ruby_xml_version.h} +2 -2
  55. data/ext/libxml/ruby_xml_xinclude.c +2 -8
  56. data/ext/libxml/ruby_xml_xinclude.h +2 -2
  57. data/ext/libxml/ruby_xml_xpath.c +17 -18
  58. data/ext/libxml/ruby_xml_xpath.h +2 -2
  59. data/ext/libxml/ruby_xml_xpath_context.c +387 -389
  60. data/ext/libxml/ruby_xml_xpath_context.h +2 -2
  61. data/ext/libxml/ruby_xml_xpath_expression.c +18 -8
  62. data/ext/libxml/ruby_xml_xpath_expression.h +1 -1
  63. data/ext/libxml/ruby_xml_xpath_object.c +19 -8
  64. data/ext/libxml/ruby_xml_xpath_object.h +1 -1
  65. data/ext/libxml/ruby_xml_xpointer.c +2 -8
  66. data/ext/libxml/ruby_xml_xpointer.h +2 -2
  67. data/ext/mingw/libxml_ruby.dll.a +0 -0
  68. data/ext/mingw/libxml_ruby.so +0 -0
  69. data/ext/vc/libxml_ruby.sln +7 -1
  70. data/lib/libxml.rb +1 -12
  71. data/lib/libxml/attr.rb +0 -3
  72. data/lib/libxml/attr_decl.rb +0 -3
  73. data/lib/libxml/attributes.rb +0 -3
  74. data/lib/libxml/document.rb +31 -5
  75. data/lib/libxml/error.rb +8 -4
  76. data/lib/libxml/properties.rb +0 -5
  77. data/lib/libxml/sax_callbacks.rb +30 -19
  78. data/lib/libxml/tree.rb +0 -1
  79. data/lib/libxml/xpath_object.rb +0 -13
  80. data/test/model/definition.dtd +8 -0
  81. data/test/tc_attributes.rb +4 -1
  82. data/test/tc_document.rb +16 -0
  83. data/test/tc_dtd.rb +30 -2
  84. data/test/tc_html_parser.rb +55 -10
  85. data/test/tc_node.rb +67 -1
  86. data/test/tc_node_edit.rb +26 -6
  87. data/test/tc_node_text.rb +41 -23
  88. data/test/tc_parser.rb +50 -0
  89. data/test/tc_reader.rb +15 -0
  90. data/test/tc_relaxng.rb +1 -1
  91. data/test/tc_sax_parser.rb +37 -5
  92. data/test/tc_schema.rb +1 -1
  93. data/test/tc_xpath.rb +1 -0
  94. data/test/tc_xpath_expression.rb +4 -2
  95. metadata +6 -6
  96. data/ext/libxml/ruby_xml_state.c +0 -51
  97. data/ext/libxml/ruby_xml_state.h +0 -11
  98. data/ext/vc/libxml_ruby.vcproj +0 -460
@@ -6,7 +6,7 @@
6
6
 
7
7
  extern VALUE cXMLReader;
8
8
 
9
- void ruby_init_xml_reader(void);
9
+ void rxml_init_reader(void);
10
10
 
11
11
  /* Exported to be used by XML::Document#reader */
12
12
  VALUE rxml_reader_new_walker(VALUE self, VALUE doc);
@@ -32,12 +32,6 @@
32
32
 
33
33
  VALUE cXMLRelaxNG;
34
34
 
35
- // Rdoc needs to know
36
- #ifdef RDOC_NEVER_DEFINED
37
- mLibXML = rb_define_module("LibXML");
38
- mXML = rb_define_module_under(mLibXML, "XML");
39
- #endif
40
-
41
35
  static void rxml_relaxng_free(xmlRelaxNGPtr xrelaxng)
42
36
  {
43
37
  xmlRelaxNGFree(xrelaxng);
@@ -105,7 +99,7 @@ static VALUE rxml_relaxng_init_from_string(VALUE self, VALUE relaxng_str)
105
99
  return Data_Wrap_Struct(cXMLRelaxNG, NULL, rxml_relaxng_free, xrelaxng);
106
100
  }
107
101
 
108
- void ruby_init_xml_relaxng(void)
102
+ void rxml_init_relaxng(void)
109
103
  {
110
104
  cXMLRelaxNG = rb_define_class_under(mXML, "RelaxNG", rb_cObject);
111
105
  rb_define_singleton_method(cXMLRelaxNG, "new", rxml_relaxng_init_from_uri, 1);
@@ -5,6 +5,6 @@
5
5
 
6
6
  extern VALUE cXMLRelaxNG;
7
7
 
8
- void ruby_init_xml_relaxng(void);
8
+ void rxml_init_relaxng(void);
9
9
  #endif
10
10
 
@@ -222,7 +222,7 @@ static void start_element_ns_callback(void *ctx,
222
222
  {
223
223
  VALUE nsPrefix = xnamespaces[i+0] ? rb_str_new2(xnamespaces[i+0]) : Qnil;
224
224
  VALUE nsURI = xnamespaces[i+1] ? rb_str_new2(xnamespaces[i+1]) : Qnil;
225
- rb_hash_aset(attributes, nsPrefix, nsURI);
225
+ rb_hash_aset(namespaces, nsPrefix, nsURI);
226
226
  }
227
227
  }
228
228
 
@@ -298,7 +298,7 @@ xmlSAXHandler rxml_sax_handler = {
298
298
  (xmlStructuredErrorFunc) structured_error_callback
299
299
  };
300
300
 
301
- void ruby_init_xml_sax2_handler(void)
301
+ void rxml_init_sax2_handler(void)
302
302
  {
303
303
 
304
304
  /* SaxCallbacks */
@@ -7,6 +7,6 @@
7
7
 
8
8
  extern xmlSAXHandler rxml_sax_handler;
9
9
 
10
- void ruby_init_xml_sax2_handler(void);
10
+ void rxml_init_sax2_handler(void);
11
11
 
12
12
  #endif
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_sax_parser.c 740 2009-01-23 04:03:11Z cfis $ */
1
+ /* $Id: ruby_xml_sax_parser.c 758 2009-01-25 20:36:03Z cfis $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -121,13 +121,7 @@ static VALUE rxml_sax_parser_parse(VALUE self)
121
121
  return Qtrue;
122
122
  }
123
123
 
124
- // Rdoc needs to know
125
- #ifdef RDOC_NEVER_DEFINED
126
- mLibXML = rb_define_module("LibXML");
127
- mXML = rb_define_module_under(mLibXML, "XML");
128
- #endif
129
-
130
- void ruby_init_xml_sax_parser(void)
124
+ void rxml_init_sax_parser(void)
131
125
  {
132
126
  /* SaxParser */
133
127
  cXMLSaxParser = rb_define_class_under(mXML, "SaxParser", rb_cObject);
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_sax_parser.h 666 2008-12-07 00:16:50Z cfis $ */
1
+ /* $Id: ruby_xml_sax_parser.h 758 2009-01-25 20:36:03Z cfis $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -7,6 +7,6 @@
7
7
 
8
8
  extern VALUE cXMLSaxParser;
9
9
 
10
- void ruby_init_xml_sax_parser(void);
10
+ void rxml_init_sax_parser(void);
11
11
 
12
12
  #endif
@@ -32,12 +32,6 @@
32
32
 
33
33
  VALUE cXMLSchema;
34
34
 
35
- // Rdoc needs to know
36
- #ifdef RDOC_NEVER_DEFINED
37
- mLibXML = rb_define_module("LibXML");
38
- mXML = rb_define_module_under(mLibXML, "XML");
39
- #endif
40
-
41
35
  static void rxml_schema_free(xmlSchemaPtr xschema)
42
36
  {
43
37
  xmlSchemaFree(xschema);
@@ -153,7 +147,7 @@ static VALUE rxml_schema_init_from_string(VALUE self, VALUE schema_str)
153
147
  } else if (!strcmp(method, "validate_schema_buffer")) {
154
148
  */
155
149
 
156
- void ruby_init_xml_schema(void)
150
+ void rxml_init_schema(void)
157
151
  {
158
152
  cXMLSchema = rb_define_class_under(mXML, "Schema", rb_cObject);
159
153
  rb_define_singleton_method(cXMLSchema, "new", rxml_schema_init_from_uri, 1);
@@ -6,6 +6,6 @@
6
6
 
7
7
  extern VALUE cXMLSchema;
8
8
 
9
- void ruby_init_xml_schema(void);
9
+ void rxml_init_schema(void);
10
10
  #endif
11
11
 
@@ -1,9 +1,9 @@
1
1
  /* Don't nuke this block! It is used for automatically updating the
2
2
  * versions below. VERSION = string formatting, VERNUM = numbered
3
3
  * version for inline testing: increment both or none at all.*/
4
- #define RUBY_LIBXML_VERSION "0.9.8"
4
+ #define RUBY_LIBXML_VERSION "0.9.9"
5
5
  #define RUBY_LIBXML_VERNUM 0
6
6
  #define RUBY_LIBXML_VER_MAJ 0
7
7
  #define RUBY_LIBXML_VER_MIN 9
8
- #define RUBY_LIBXML_VER_MIC 8
8
+ #define RUBY_LIBXML_VER_MIC 9
9
9
  #define RUBY_LIBXML_VER_PATCH 0
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_xinclude.c 650 2008-11-30 03:40:22Z cfis $ */
1
+ /* $Id: ruby_xml_xinclude.c 758 2009-01-25 20:36:03Z cfis $ */
2
2
 
3
3
  #include "ruby_libxml.h"
4
4
  #include "ruby_xml_xinclude.h"
@@ -12,13 +12,7 @@ VALUE cXMLXInclude;
12
12
  * XInclude fuctionality.
13
13
  */
14
14
 
15
- // Rdoc needs to know
16
- #ifdef RDOC_NEVER_DEFINED
17
- mLibXML = rb_define_module("LibXML");
18
- mXML = rb_define_module_under(mLibXML, "XML");
19
- #endif
20
-
21
- void ruby_init_xml_xinclude(void)
15
+ void rxml_init_xinclude(void)
22
16
  {
23
17
  cXMLXInclude = rb_define_class_under(mXML, "XInclude", rb_cObject);
24
18
  }
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_xinclude.h 666 2008-12-07 00:16:50Z cfis $ */
1
+ /* $Id: ruby_xml_xinclude.h 758 2009-01-25 20:36:03Z cfis $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -8,6 +8,6 @@
8
8
  extern VALUE cXMLXInclude;
9
9
  extern VALUE eXMLXIncludeError;
10
10
 
11
- void ruby_init_xml_xinclude(void);
11
+ void rxml_init_xinclude(void);
12
12
 
13
13
  #endif
@@ -1,10 +1,4 @@
1
- /* $Id: ruby_xml_xpath.c 666 2008-12-07 00:16:50Z cfis $ */
2
-
3
- /* Please see the LICENSE file for copyright and distribution information */
4
-
5
- #include "ruby_libxml.h"
6
- #include "ruby_xml_xpath.h"
7
- #include "ruby_xml_xpath_context.h"
1
+ /* $Id: ruby_xml_xpath.c 759 2009-01-26 00:15:49Z cfis $ */
8
2
 
9
3
  /*
10
4
  * Document-class: LibXML::XML::XPath
@@ -78,31 +72,36 @@
78
72
  * # Here is an example showing a complex namespace aware
79
73
  * # xpath expression.
80
74
  * doc.find('/soap:Envelope/soap:Body/ns0:getManufacturerNamesResponse/ns0:IDAndNameList/ns1:IdAndName',
81
- ['ns0:http://services.somewhere.com', 'ns1:http://domain.somewhere.com'])
82
- */
75
+ * ['ns0:http://services.somewhere.com', 'ns1:http://domain.somewhere.com'])
76
+ */
83
77
 
84
- VALUE mXPath;
85
78
 
86
- // Rdoc needs to know
87
- #ifdef RDOC_NEVER_DEFINED
88
- mLibXML = rb_define_module("LibXML");
89
- mXML = rb_define_module_under(mLibXML, "XML");
90
- #endif
79
+ #include "ruby_libxml.h"
80
+
81
+ VALUE mXPath;
91
82
 
92
- void ruby_init_xml_xpath(void)
83
+ void rxml_init_xpath(void)
93
84
  {
94
85
  mXPath = rb_define_module_under(mXML, "XPath");
95
86
 
87
+ /* 0: Undefined value. */
96
88
  rb_define_const(mXPath, "UNDEFINED", INT2NUM(XPATH_UNDEFINED));
89
+ /* 1: A nodeset, will be wrapped by XPath Object. */
97
90
  rb_define_const(mXPath, "NODESET", INT2NUM(XPATH_NODESET));
91
+ /* 2: A boolean value. */
98
92
  rb_define_const(mXPath, "BOOLEAN", INT2NUM(XPATH_BOOLEAN));
93
+ /* 3: A numeric value. */
99
94
  rb_define_const(mXPath, "NUMBER", INT2NUM(XPATH_NUMBER));
95
+ /* 4: A string value. */
100
96
  rb_define_const(mXPath, "STRING", INT2NUM(XPATH_STRING));
97
+ /* 5: An xpointer point */
101
98
  rb_define_const(mXPath, "POINT", INT2NUM(XPATH_POINT));
99
+ /* 6: An xpointer range */
102
100
  rb_define_const(mXPath, "RANGE", INT2NUM(XPATH_RANGE));
101
+ /* 7: An xpointer location set */
103
102
  rb_define_const(mXPath, "LOCATIONSET", INT2NUM(XPATH_LOCATIONSET));
103
+ /* 8: XPath user type */
104
104
  rb_define_const(mXPath, "USERS", INT2NUM(XPATH_USERS));
105
+ /* 9: An XSLT value tree, non modifiable */
105
106
  rb_define_const(mXPath, "XSLT_TREE", INT2NUM(XPATH_XSLT_TREE));
106
-
107
- ruby_init_xml_xpath_object();
108
107
  }
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_xpath.h 666 2008-12-07 00:16:50Z cfis $ */
1
+ /* $Id: ruby_xml_xpath.h 758 2009-01-25 20:36:03Z cfis $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -7,6 +7,6 @@
7
7
 
8
8
  extern VALUE mXPath;
9
9
 
10
- void ruby_init_xml_xpath(void);
10
+ void rxml_init_xpath(void);
11
11
 
12
12
  #endif
@@ -1,389 +1,387 @@
1
- /* $Id: ruby_xml_xpath_context.c 739 2009-01-23 03:42:09Z cfis $ */
2
-
3
- /* Please see the LICENSE file for copyright and distribution information */
4
-
5
- #include "ruby_libxml.h"
6
- #include "ruby_xml_xpath_context.h"
7
- #include "ruby_xml_xpath_expression.h"
8
- #include <st.h>
9
-
10
- /*
11
- * Document-class: LibXML::XML::XPath::Context
12
- *
13
- * The XML::XPath::Context class is used to evaluate XPath
14
- * expressions. Generally, you should not directly use this class,
15
- * but instead use the XML::Document#find and XML::Node#find methods.
16
- *
17
- * doc = XML::Document.string('<header>content</header>')
18
- * context = XPath::Context.new(doc)
19
- * context.node = doc.root
20
- * context.register_namespaces_from_node(doc.root)
21
- * nodes = context.find('/header')
22
- */
23
-
24
- VALUE cXMLXPathContext;
25
-
26
- static ID DOC_ATTRIBUTE;
27
-
28
- static void rxml_xpath_context_free(xmlXPathContextPtr ctxt)
29
- {
30
- xmlXPathFreeContext(ctxt);
31
- }
32
-
33
- static VALUE rxml_xpath_context_alloc(VALUE klass)
34
- {
35
- return Data_Wrap_Struct(cXMLXPathContext, NULL, rxml_xpath_context_free, NULL);
36
- }
37
-
38
- /* call-seq:
39
- * XPath::Context.new(node) -> XPath::Context
40
- *
41
- * Creates a new XPath context for the specified document. The
42
- * context can then be used to evaluate an XPath expression.
43
- *
44
- * doc = XML::Document.string('<header><first>hi</first></header>')
45
- * context = XPath::Context.new(doc)
46
- * nodes = XPath::Object.new('//first', context)
47
- * nodes.length == 1
48
- */
49
- static VALUE rxml_xpath_context_initialize(VALUE self, VALUE node)
50
- {
51
- xmlDocPtr xdoc;
52
- VALUE document;
53
-
54
- if (rb_obj_is_kind_of(node, cXMLNode) == Qtrue)
55
- {
56
- document = rb_funcall(node, rb_intern("doc"), 0);
57
- if (NIL_P(document))
58
- rb_raise(rb_eTypeError, "Supplied node must belong to a document.");
59
- }
60
- else if (rb_obj_is_kind_of(node, cXMLDocument) == Qtrue)
61
- {
62
- document = node;
63
- }
64
- else
65
- {
66
- rb_raise(rb_eTypeError, "Supplied argument must be a document or node.");
67
- }
68
-
69
- Data_Get_Struct(document, xmlDoc, xdoc);
70
- DATA_PTR(self) = xmlXPathNewContext(xdoc);
71
-
72
- /* Save the doc as an attribute, this will expose it to Ruby's GC. */
73
- rb_ivar_set(self, DOC_ATTRIBUTE, document);
74
-
75
- return self;
76
- }
77
-
78
- /*
79
- * call-seq:
80
- * context.register_namespace(prefix, uri) -> (true|false)
81
- *
82
- * Register the specified namespace URI with the specified prefix
83
- * in this context.
84
-
85
- * context.register_namespace('xi', 'http://www.w3.org/2001/XInclude')
86
- */
87
- static VALUE rxml_xpath_context_register_namespace(VALUE self, VALUE prefix, VALUE uri)
88
- {
89
- xmlXPathContextPtr ctxt;
90
- Data_Get_Struct(self, xmlXPathContext, ctxt);
91
-
92
- /* Prefix could be a symbol. */
93
- prefix = rb_obj_as_string(prefix);
94
-
95
- if (xmlXPathRegisterNs(ctxt, (xmlChar*) StringValuePtr(prefix),
96
- (xmlChar*) StringValuePtr(uri)) == 0)
97
- {
98
- return (Qtrue);
99
- }
100
- else
101
- {
102
- /* Should raise an exception, IMHO (whose?, why shouldnt it? -danj)*/
103
- rb_warning("register namespace failed");
104
- return (Qfalse);
105
- }
106
- }
107
-
108
- /* call-seq:
109
- * context.register_namespaces_from_node(node) -> self
110
- *
111
- * Helper method to read in namespaces defined on a node.
112
- *
113
- * doc = XML::Document.string('<header><first>hi</first></header>')
114
- * context = XPath::Context.new(doc)
115
- * context.register_namespaces_from_node(doc.root)
116
- */
117
- static VALUE rxml_xpath_context_register_namespaces_from_node(VALUE self,
118
- VALUE node)
119
- {
120
- xmlXPathContextPtr xctxt;
121
- xmlNodePtr xnode;
122
- xmlNsPtr *xnsArr;
123
-
124
- Data_Get_Struct(self, xmlXPathContext, xctxt);
125
-
126
- if (rb_obj_is_kind_of(node, cXMLDocument) == Qtrue)
127
- {
128
- xmlDocPtr xdoc;
129
- Data_Get_Struct(node, xmlDoc, xdoc);
130
- xnode = xmlDocGetRootElement(xdoc);
131
- }
132
- else if (rb_obj_is_kind_of(node, cXMLNode) == Qtrue)
133
- {
134
- Data_Get_Struct(node, xmlNode, xnode);
135
- }
136
- else
137
- {
138
- rb_raise(rb_eTypeError, "The first argument must be a document or node.");
139
- }
140
-
141
- xnsArr = xmlGetNsList(xnode->doc, xnode);
142
-
143
- if (xnsArr)
144
- {
145
- xmlNsPtr xns = *xnsArr;
146
-
147
- while (xns)
148
- {
149
- /* If there is no prefix, then this is the default namespace.
150
- Skip it for now. */
151
- if (xns->prefix)
152
- {
153
- VALUE prefix = rb_str_new2((const char*)xns->prefix);
154
- VALUE uri = rb_str_new2((const char*)xns->href);
155
- rxml_xpath_context_register_namespace(self, prefix, uri);
156
- }
157
- xns = xns->next;
158
- }
159
- xmlFree(xnsArr);
160
- }
161
-
162
- return self;
163
- }
164
-
165
- static int iterate_ns_hash(st_data_t prefix, st_data_t uri, st_data_t self)
166
- {
167
- rxml_xpath_context_register_namespace(self, prefix, uri);
168
- return ST_CONTINUE;
169
- }
170
-
171
- /*
172
- * call-seq:
173
- * context.register_namespaces(["prefix:uri"]) -> self
174
- *
175
- * Register the specified namespaces in this context. There are
176
- * three different forms that libxml accepts. These include
177
- * a string, an array of strings, or a hash table:
178
- *
179
- * context.register_namespaces('xi:http://www.w3.org/2001/XInclude')
180
- * context.register_namespaces(['xlink:http://www.w3.org/1999/xlink',
181
- * 'xi:http://www.w3.org/2001/XInclude')
182
- * context.register_namespaces('xlink' => 'http://www.w3.org/1999/xlink',
183
- * 'xi' => 'http://www.w3.org/2001/XInclude')
184
- */
185
- static VALUE rxml_xpath_context_register_namespaces(VALUE self, VALUE nslist)
186
- {
187
- char *cp;
188
- long i;
189
- VALUE rprefix, ruri;
190
-
191
- /* Need to loop through the 2nd argument and iterate through the
192
- * list of namespaces that we want to allow */
193
- switch (TYPE(nslist))
194
- {
195
- case T_STRING:
196
- cp = strchr(StringValuePtr(nslist), (int) ':');
197
- if (cp == NULL)
198
- {
199
- rprefix = nslist;
200
- ruri = Qnil;
201
- }
202
- else
203
- {
204
- rprefix = rb_str_new(StringValuePtr(nslist), (int) ((long) cp
205
- - (long) StringValuePtr(nslist)));
206
- ruri = rb_str_new2(&cp[1]);
207
- }
208
- /* Should test the results of this */
209
- rxml_xpath_context_register_namespace(self, rprefix, ruri);
210
- break;
211
- case T_ARRAY:
212
- for (i = 0; i < RARRAY_LEN(nslist); i++)
213
- {
214
- rxml_xpath_context_register_namespaces(self, RARRAY_PTR(nslist)[i]);
215
- }
216
- break;
217
- case T_HASH:
218
- st_foreach(RHASH_TBL(nslist), iterate_ns_hash, self);
219
- break;
220
- default:
221
- rb_raise(
222
- rb_eArgError,
223
- "Invalid argument type, only accept string, array of strings, or an array of arrays");
224
- }
225
- return self;
226
- }
227
-
228
- /*
229
- * call-seq:
230
- * context.node = node
231
- *
232
- * Set the current node used by the XPath engine
233
-
234
- * doc = XML::Document.string('<header><first>hi</first></header>')
235
- * context.node = doc.root.first
236
- */
237
- static VALUE rxml_xpath_context_node_set(VALUE self, VALUE node)
238
- {
239
- xmlXPathContextPtr xctxt;
240
- xmlNodePtr xnode;
241
-
242
- Data_Get_Struct(self, xmlXPathContext, xctxt);
243
- Data_Get_Struct(node, xmlNode, xnode);
244
- xctxt->node = xnode;
245
- return node;
246
- }
247
-
248
- /*
249
- * call-seq:
250
- * context.find("xpath") -> true|false|number|string|XML::XPath::Object
251
- *
252
- * Executes the provided xpath function. The result depends on the execution
253
- * of the xpath statement. It may be true, false, a number, a string or
254
- * a node set.
255
- */
256
- static VALUE rxml_xpath_context_find(VALUE self, VALUE xpath_expr)
257
- {
258
- xmlXPathContextPtr xctxt;
259
- xmlXPathObjectPtr xobject;
260
- xmlXPathCompExprPtr xcompexpr;
261
- VALUE result;
262
-
263
- Data_Get_Struct(self, xmlXPathContext, xctxt);
264
-
265
- if (TYPE(xpath_expr) == T_STRING)
266
- {
267
- VALUE expression = rb_check_string_type(xpath_expr);
268
- xobject = xmlXPathEval((xmlChar*) StringValueCStr(expression), xctxt);
269
- }
270
- else if (rb_obj_is_kind_of(xpath_expr, cXMLXPathExpression))
271
- {
272
- Data_Get_Struct(xpath_expr, xmlXPathCompExpr, xcompexpr);
273
- xobject = xmlXPathCompiledEval(xcompexpr, xctxt);
274
- }
275
- else
276
- {
277
- rb_raise(rb_eTypeError,
278
- "Argument should be an intance of a String or XPath::Expression");
279
- }
280
-
281
- if (xobject == NULL)
282
- {
283
- /* xmlLastError is different than xctxt->lastError. Use
284
- xmlLastError since it has the message set while xctxt->lastError
285
- does not. */
286
- xmlErrorPtr xerror = xmlGetLastError();
287
- rxml_raise(xerror);
288
- }
289
-
290
- switch (xobject->type)
291
- {
292
- case XPATH_NODESET:
293
- result = rxml_xpath_object_wrap(xctxt->doc, xobject);
294
- break;
295
- case XPATH_BOOLEAN:
296
- result = (xobject->boolval != 0) ? Qtrue : Qfalse;
297
- xmlXPathFreeObject(xobject);
298
- break;
299
- case XPATH_NUMBER:
300
- result = rb_float_new(xobject->floatval);
301
- xmlXPathFreeObject(xobject);
302
- break;
303
- case XPATH_STRING:
304
- result = rb_str_new2((const char*)xobject->stringval);
305
- xmlXPathFreeObject(xobject);
306
- break;
307
- default:
308
- result = Qnil;
309
- xmlXPathFreeObject(xobject);
310
- }
311
- return result;
312
- }
313
-
314
- #if LIBXML_VERSION >= 20626
315
- /*
316
- * call-seq:
317
- * context.enable_cache(size = nil)
318
- *
319
- * Enables an XPath::Context's built-in cache. If the cache is
320
- * enabled then XPath objects will be cached internally for reuse.
321
- * The size parameter controls sets the maximum number of XPath objects
322
- * that will be cached per XPath object type (node-set, string, number,
323
- * boolean, and misc objects). Set size to nil to use the default
324
- * cache size of 100.
325
- */
326
- static VALUE
327
- rxml_xpath_context_enable_cache(int argc, VALUE *argv, VALUE self)
328
- {
329
- xmlXPathContextPtr xctxt;
330
- VALUE size;
331
- int value = -1;
332
-
333
- Data_Get_Struct(self, xmlXPathContext, xctxt);
334
-
335
- if (rb_scan_args(argc, argv, "01", &size) == 1)
336
- {
337
- value = NUM2INT(size);
338
- }
339
-
340
- if (xmlXPathContextSetCache(xctxt, 1, value, 0) == -1)
341
- rxml_raise(&xmlLastError);
342
-
343
- return self;
344
- }
345
-
346
- /*
347
- * call-seq:
348
- * context.disable_cache
349
- *
350
- * Disables an XPath::Context's built-in cache.
351
- */
352
- static VALUE
353
- rxml_xpath_context_disable_cache(VALUE self)
354
- {
355
- xmlXPathContextPtr xctxt;
356
- Data_Get_Struct(self, xmlXPathContext, xctxt);
357
-
358
- if (xmlXPathContextSetCache(xctxt, 0, 0, 0) == -1)
359
- rxml_raise(&xmlLastError);
360
-
361
- return self;
362
- }
363
- #endif
364
-
365
-
366
- // Rdoc needs to know
367
- #ifdef RDOC_NEVER_DEFINED
368
- mLibXML = rb_define_module("LibXML");
369
- mXPath = rb_define_module_under(mLibXML, "XPath");
370
- #endif
371
-
372
- void ruby_init_xml_xpath_context(void)
373
- {
374
- DOC_ATTRIBUTE = rb_intern("@doc");
375
-
376
- cXMLXPathContext = rb_define_class_under(mXPath, "Context", rb_cObject);
377
- rb_define_alloc_func(cXMLXPathContext, rxml_xpath_context_alloc);
378
- rb_define_attr(cXMLXPathContext, "doc", 1, 0);
379
- rb_define_method(cXMLXPathContext, "initialize", rxml_xpath_context_initialize, 1);
380
- rb_define_method(cXMLXPathContext, "register_namespaces", rxml_xpath_context_register_namespaces, 1);
381
- rb_define_method(cXMLXPathContext, "register_namespaces_from_node", rxml_xpath_context_register_namespaces_from_node, 1);
382
- rb_define_method(cXMLXPathContext, "register_namespace", rxml_xpath_context_register_namespace, 2);
383
- rb_define_method(cXMLXPathContext, "node=", rxml_xpath_context_node_set, 1);
384
- rb_define_method(cXMLXPathContext, "find", rxml_xpath_context_find, 1);
385
- #if LIBXML_VERSION >= 20626
386
- rb_define_method(cXMLXPathContext, "enable_cache", rxml_xpath_context_enable_cache, -1);
387
- rb_define_method(cXMLXPathContext, "disable_cache", rxml_xpath_context_disable_cache, 0);
388
- #endif
389
- }
1
+ /* $Id: ruby_xml_xpath_context.c 799 2009-03-02 01:45:24Z cfis $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ #include "ruby_libxml.h"
6
+ #include "ruby_xml_xpath_context.h"
7
+ #include "ruby_xml_xpath_expression.h"
8
+
9
+ #if RUBY_ST_H
10
+ #include <ruby/st.h>
11
+ #else
12
+ #include <st.h>
13
+ #endif
14
+
15
+ /*
16
+ * Document-class: LibXML::XML::XPath::Context
17
+ *
18
+ * The XML::XPath::Context class is used to evaluate XPath
19
+ * expressions. Generally, you should not directly use this class,
20
+ * but instead use the XML::Document#find and XML::Node#find methods.
21
+ *
22
+ * doc = XML::Document.string('<header>content</header>')
23
+ * context = XPath::Context.new(doc)
24
+ * context.node = doc.root
25
+ * context.register_namespaces_from_node(doc.root)
26
+ * nodes = context.find('/header')
27
+ */
28
+
29
+ VALUE cXMLXPathContext;
30
+
31
+ static ID DOC_ATTRIBUTE;
32
+
33
+ static void rxml_xpath_context_free(xmlXPathContextPtr ctxt)
34
+ {
35
+ xmlXPathFreeContext(ctxt);
36
+ }
37
+
38
+ static VALUE rxml_xpath_context_alloc(VALUE klass)
39
+ {
40
+ return Data_Wrap_Struct(cXMLXPathContext, NULL, rxml_xpath_context_free, NULL);
41
+ }
42
+
43
+ /* call-seq:
44
+ * XPath::Context.new(node) -> XPath::Context
45
+ *
46
+ * Creates a new XPath context for the specified document. The
47
+ * context can then be used to evaluate an XPath expression.
48
+ *
49
+ * doc = XML::Document.string('<header><first>hi</first></header>')
50
+ * context = XPath::Context.new(doc)
51
+ * nodes = XPath::Object.new('//first', context)
52
+ * nodes.length == 1
53
+ */
54
+ static VALUE rxml_xpath_context_initialize(VALUE self, VALUE node)
55
+ {
56
+ xmlDocPtr xdoc;
57
+ VALUE document;
58
+
59
+ if (rb_obj_is_kind_of(node, cXMLNode) == Qtrue)
60
+ {
61
+ document = rb_funcall(node, rb_intern("doc"), 0);
62
+ if (NIL_P(document))
63
+ rb_raise(rb_eTypeError, "Supplied node must belong to a document.");
64
+ }
65
+ else if (rb_obj_is_kind_of(node, cXMLDocument) == Qtrue)
66
+ {
67
+ document = node;
68
+ }
69
+ else
70
+ {
71
+ rb_raise(rb_eTypeError, "Supplied argument must be a document or node.");
72
+ }
73
+
74
+ Data_Get_Struct(document, xmlDoc, xdoc);
75
+ DATA_PTR(self) = xmlXPathNewContext(xdoc);
76
+
77
+ /* Save the doc as an attribute, this will expose it to Ruby's GC. */
78
+ rb_ivar_set(self, DOC_ATTRIBUTE, document);
79
+
80
+ return self;
81
+ }
82
+
83
+ /*
84
+ * call-seq:
85
+ * context.register_namespace(prefix, uri) -> (true|false)
86
+ *
87
+ * Register the specified namespace URI with the specified prefix
88
+ * in this context.
89
+
90
+ * context.register_namespace('xi', 'http://www.w3.org/2001/XInclude')
91
+ */
92
+ static VALUE rxml_xpath_context_register_namespace(VALUE self, VALUE prefix, VALUE uri)
93
+ {
94
+ xmlXPathContextPtr ctxt;
95
+ Data_Get_Struct(self, xmlXPathContext, ctxt);
96
+
97
+ /* Prefix could be a symbol. */
98
+ prefix = rb_obj_as_string(prefix);
99
+
100
+ if (xmlXPathRegisterNs(ctxt, (xmlChar*) StringValuePtr(prefix),
101
+ (xmlChar*) StringValuePtr(uri)) == 0)
102
+ {
103
+ return (Qtrue);
104
+ }
105
+ else
106
+ {
107
+ /* Should raise an exception, IMHO (whose?, why shouldnt it? -danj)*/
108
+ rb_warning("register namespace failed");
109
+ return (Qfalse);
110
+ }
111
+ }
112
+
113
+ /* call-seq:
114
+ * context.register_namespaces_from_node(node) -> self
115
+ *
116
+ * Helper method to read in namespaces defined on a node.
117
+ *
118
+ * doc = XML::Document.string('<header><first>hi</first></header>')
119
+ * context = XPath::Context.new(doc)
120
+ * context.register_namespaces_from_node(doc.root)
121
+ */
122
+ static VALUE rxml_xpath_context_register_namespaces_from_node(VALUE self,
123
+ VALUE node)
124
+ {
125
+ xmlXPathContextPtr xctxt;
126
+ xmlNodePtr xnode;
127
+ xmlNsPtr *xnsArr;
128
+
129
+ Data_Get_Struct(self, xmlXPathContext, xctxt);
130
+
131
+ if (rb_obj_is_kind_of(node, cXMLDocument) == Qtrue)
132
+ {
133
+ xmlDocPtr xdoc;
134
+ Data_Get_Struct(node, xmlDoc, xdoc);
135
+ xnode = xmlDocGetRootElement(xdoc);
136
+ }
137
+ else if (rb_obj_is_kind_of(node, cXMLNode) == Qtrue)
138
+ {
139
+ Data_Get_Struct(node, xmlNode, xnode);
140
+ }
141
+ else
142
+ {
143
+ rb_raise(rb_eTypeError, "The first argument must be a document or node.");
144
+ }
145
+
146
+ xnsArr = xmlGetNsList(xnode->doc, xnode);
147
+
148
+ if (xnsArr)
149
+ {
150
+ xmlNsPtr xns = *xnsArr;
151
+
152
+ while (xns)
153
+ {
154
+ /* If there is no prefix, then this is the default namespace.
155
+ Skip it for now. */
156
+ if (xns->prefix)
157
+ {
158
+ VALUE prefix = rb_str_new2((const char*)xns->prefix);
159
+ VALUE uri = rb_str_new2((const char*)xns->href);
160
+ rxml_xpath_context_register_namespace(self, prefix, uri);
161
+ }
162
+ xns = xns->next;
163
+ }
164
+ xmlFree(xnsArr);
165
+ }
166
+
167
+ return self;
168
+ }
169
+
170
+ static int iterate_ns_hash(st_data_t prefix, st_data_t uri, st_data_t self)
171
+ {
172
+ rxml_xpath_context_register_namespace(self, prefix, uri);
173
+ return ST_CONTINUE;
174
+ }
175
+
176
+ /*
177
+ * call-seq:
178
+ * context.register_namespaces(["prefix:uri"]) -> self
179
+ *
180
+ * Register the specified namespaces in this context. There are
181
+ * three different forms that libxml accepts. These include
182
+ * a string, an array of strings, or a hash table:
183
+ *
184
+ * context.register_namespaces('xi:http://www.w3.org/2001/XInclude')
185
+ * context.register_namespaces(['xlink:http://www.w3.org/1999/xlink',
186
+ * 'xi:http://www.w3.org/2001/XInclude')
187
+ * context.register_namespaces('xlink' => 'http://www.w3.org/1999/xlink',
188
+ * 'xi' => 'http://www.w3.org/2001/XInclude')
189
+ */
190
+ static VALUE rxml_xpath_context_register_namespaces(VALUE self, VALUE nslist)
191
+ {
192
+ char *cp;
193
+ long i;
194
+ VALUE rprefix, ruri;
195
+
196
+ /* Need to loop through the 2nd argument and iterate through the
197
+ * list of namespaces that we want to allow */
198
+ switch (TYPE(nslist))
199
+ {
200
+ case T_STRING:
201
+ cp = strchr(StringValuePtr(nslist), (int) ':');
202
+ if (cp == NULL)
203
+ {
204
+ rprefix = nslist;
205
+ ruri = Qnil;
206
+ }
207
+ else
208
+ {
209
+ rprefix = rb_str_new(StringValuePtr(nslist), (int) ((long) cp
210
+ - (long) StringValuePtr(nslist)));
211
+ ruri = rb_str_new2(&cp[1]);
212
+ }
213
+ /* Should test the results of this */
214
+ rxml_xpath_context_register_namespace(self, rprefix, ruri);
215
+ break;
216
+ case T_ARRAY:
217
+ for (i = 0; i < RARRAY_LEN(nslist); i++)
218
+ {
219
+ rxml_xpath_context_register_namespaces(self, RARRAY_PTR(nslist)[i]);
220
+ }
221
+ break;
222
+ case T_HASH:
223
+ st_foreach(RHASH_TBL(nslist), iterate_ns_hash, self);
224
+ break;
225
+ default:
226
+ rb_raise(
227
+ rb_eArgError,
228
+ "Invalid argument type, only accept string, array of strings, or an array of arrays");
229
+ }
230
+ return self;
231
+ }
232
+
233
+ /*
234
+ * call-seq:
235
+ * context.node = node
236
+ *
237
+ * Set the current node used by the XPath engine
238
+
239
+ * doc = XML::Document.string('<header><first>hi</first></header>')
240
+ * context.node = doc.root.first
241
+ */
242
+ static VALUE rxml_xpath_context_node_set(VALUE self, VALUE node)
243
+ {
244
+ xmlXPathContextPtr xctxt;
245
+ xmlNodePtr xnode;
246
+
247
+ Data_Get_Struct(self, xmlXPathContext, xctxt);
248
+ Data_Get_Struct(node, xmlNode, xnode);
249
+ xctxt->node = xnode;
250
+ return node;
251
+ }
252
+
253
+ /*
254
+ * call-seq:
255
+ * context.find("xpath") -> true|false|number|string|XML::XPath::Object
256
+ *
257
+ * Executes the provided xpath function. The result depends on the execution
258
+ * of the xpath statement. It may be true, false, a number, a string or
259
+ * a node set.
260
+ */
261
+ static VALUE rxml_xpath_context_find(VALUE self, VALUE xpath_expr)
262
+ {
263
+ xmlXPathContextPtr xctxt;
264
+ xmlXPathObjectPtr xobject;
265
+ xmlXPathCompExprPtr xcompexpr;
266
+ VALUE result;
267
+
268
+ Data_Get_Struct(self, xmlXPathContext, xctxt);
269
+
270
+ if (TYPE(xpath_expr) == T_STRING)
271
+ {
272
+ VALUE expression = rb_check_string_type(xpath_expr);
273
+ xobject = xmlXPathEval((xmlChar*) StringValueCStr(expression), xctxt);
274
+ }
275
+ else if (rb_obj_is_kind_of(xpath_expr, cXMLXPathExpression))
276
+ {
277
+ Data_Get_Struct(xpath_expr, xmlXPathCompExpr, xcompexpr);
278
+ xobject = xmlXPathCompiledEval(xcompexpr, xctxt);
279
+ }
280
+ else
281
+ {
282
+ rb_raise(rb_eTypeError,
283
+ "Argument should be an intance of a String or XPath::Expression");
284
+ }
285
+
286
+ if (xobject == NULL)
287
+ {
288
+ /* xmlLastError is different than xctxt->lastError. Use
289
+ xmlLastError since it has the message set while xctxt->lastError
290
+ does not. */
291
+ xmlErrorPtr xerror = xmlGetLastError();
292
+ rxml_raise(xerror);
293
+ }
294
+
295
+ switch (xobject->type)
296
+ {
297
+ case XPATH_NODESET:
298
+ result = rxml_xpath_object_wrap(xctxt->doc, xobject);
299
+ break;
300
+ case XPATH_BOOLEAN:
301
+ result = (xobject->boolval != 0) ? Qtrue : Qfalse;
302
+ xmlXPathFreeObject(xobject);
303
+ break;
304
+ case XPATH_NUMBER:
305
+ result = rb_float_new(xobject->floatval);
306
+ xmlXPathFreeObject(xobject);
307
+ break;
308
+ case XPATH_STRING:
309
+ result = rb_str_new2((const char*)xobject->stringval);
310
+ xmlXPathFreeObject(xobject);
311
+ break;
312
+ default:
313
+ result = Qnil;
314
+ xmlXPathFreeObject(xobject);
315
+ }
316
+ return result;
317
+ }
318
+
319
+ #if LIBXML_VERSION >= 20626
320
+ /*
321
+ * call-seq:
322
+ * context.enable_cache(size = nil)
323
+ *
324
+ * Enables an XPath::Context's built-in cache. If the cache is
325
+ * enabled then XPath objects will be cached internally for reuse.
326
+ * The size parameter controls sets the maximum number of XPath objects
327
+ * that will be cached per XPath object type (node-set, string, number,
328
+ * boolean, and misc objects). Set size to nil to use the default
329
+ * cache size of 100.
330
+ */
331
+ static VALUE
332
+ rxml_xpath_context_enable_cache(int argc, VALUE *argv, VALUE self)
333
+ {
334
+ xmlXPathContextPtr xctxt;
335
+ VALUE size;
336
+ int value = -1;
337
+
338
+ Data_Get_Struct(self, xmlXPathContext, xctxt);
339
+
340
+ if (rb_scan_args(argc, argv, "01", &size) == 1)
341
+ {
342
+ value = NUM2INT(size);
343
+ }
344
+
345
+ if (xmlXPathContextSetCache(xctxt, 1, value, 0) == -1)
346
+ rxml_raise(&xmlLastError);
347
+
348
+ return self;
349
+ }
350
+
351
+ /*
352
+ * call-seq:
353
+ * context.disable_cache
354
+ *
355
+ * Disables an XPath::Context's built-in cache.
356
+ */
357
+ static VALUE
358
+ rxml_xpath_context_disable_cache(VALUE self)
359
+ {
360
+ xmlXPathContextPtr xctxt;
361
+ Data_Get_Struct(self, xmlXPathContext, xctxt);
362
+
363
+ if (xmlXPathContextSetCache(xctxt, 0, 0, 0) == -1)
364
+ rxml_raise(&xmlLastError);
365
+
366
+ return self;
367
+ }
368
+ #endif
369
+
370
+ void rxml_init_xpath_context(void)
371
+ {
372
+ DOC_ATTRIBUTE = rb_intern("@doc");
373
+
374
+ cXMLXPathContext = rb_define_class_under(mXPath, "Context", rb_cObject);
375
+ rb_define_alloc_func(cXMLXPathContext, rxml_xpath_context_alloc);
376
+ rb_define_attr(cXMLXPathContext, "doc", 1, 0);
377
+ rb_define_method(cXMLXPathContext, "initialize", rxml_xpath_context_initialize, 1);
378
+ rb_define_method(cXMLXPathContext, "register_namespaces", rxml_xpath_context_register_namespaces, 1);
379
+ rb_define_method(cXMLXPathContext, "register_namespaces_from_node", rxml_xpath_context_register_namespaces_from_node, 1);
380
+ rb_define_method(cXMLXPathContext, "register_namespace", rxml_xpath_context_register_namespace, 2);
381
+ rb_define_method(cXMLXPathContext, "node=", rxml_xpath_context_node_set, 1);
382
+ rb_define_method(cXMLXPathContext, "find", rxml_xpath_context_find, 1);
383
+ #if LIBXML_VERSION >= 20626
384
+ rb_define_method(cXMLXPathContext, "enable_cache", rxml_xpath_context_enable_cache, -1);
385
+ rb_define_method(cXMLXPathContext, "disable_cache", rxml_xpath_context_disable_cache, 0);
386
+ #endif
387
+ }