libxml-ruby 0.9.6 → 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,4 +1,26 @@
1
- (See log/ChangeLog for more detailed changes derived directly from source control.)
1
+ == 0.9.7 / 2008-12-08 Charlie Savage
2
+
3
+ * Added SAX2 support. SAX handlers now define two new callbacks,
4
+ on_start_element_ns and on_end_element_ns methods. These
5
+ new callbacks support namespaces, making them superior to the older
6
+ callbacks on_start_element and on_end_element methods. The old callbacks
7
+ are still supported, but may be deprecated in the future depending
8
+ on community feedback.
9
+
10
+ * Added SAX support for libxml's structured error handling.
11
+ That menas sax handlers now define a new callback, on_error,
12
+ which takes one parameter, an instance of XML::Error. The older
13
+ on_parser_error, on_parser_warning and on_parser_fatal_error
14
+ callbacks are no longer suported so you must port your code.
15
+ Note that the older callbacks took one string parameter, instead of
16
+ an XML::Error object.
17
+
18
+ * Experimental work-around for libxml error handling bug - see
19
+ http://mail.gnome.org/archives/xml/2008-December/msg00014.html
20
+ for more information.
21
+
22
+ * Fix compilation bugs on Solaris.
23
+
2
24
 
3
25
  == 0.9.6 / 2008-12-08 Charlie Savage
4
26
 
@@ -61,7 +83,7 @@
61
83
 
62
84
  == 0.9.3 / 2008-11-22 Charlie Savage
63
85
 
64
- * Fixed segementation fault caused by documents being freed
86
+ * Fixed segmentation fault caused by documents being freed
65
87
  before xpath results that referenced the document (take 2).
66
88
 
67
89
  * Allowed sax parser to use io stream
@@ -86,7 +108,7 @@
86
108
  wrapped by the new XML::Error class and are thrown as exceptions
87
109
  when it is appropriate.
88
110
 
89
- * Fixed segementation fault caused by documents being freed
111
+ * Fixed segmentation fault caused by documents being freed
90
112
  before xpath results that referenced the document.
91
113
 
92
114
  * Add Node#register_default_namespace to simplify default namespace handling.
data/Rakefile CHANGED
@@ -12,9 +12,9 @@ require 'date'
12
12
  # ------- Default Package ----------
13
13
  FILES = FileList[
14
14
  'Rakefile',
15
- 'README',
16
- 'LICENSE',
17
15
  'CHANGES',
16
+ 'LICENSE',
17
+ 'README',
18
18
  'setup.rb',
19
19
  'doc/**/*',
20
20
  'ext/libxml/*',
@@ -103,8 +103,7 @@ Rake::RDocTask.new("rdoc") do |rdoc|
103
103
  'lib/**/*.rb',
104
104
  'CHANGES',
105
105
  'README',
106
- 'LICENSE',
107
- 'VERSION')
106
+ 'LICENSE')
108
107
  end
109
108
 
110
109
  Rake::TestTask.new do |t|
@@ -1,86 +1,86 @@
1
- #include <string.h>
2
- #include <libxml/xmlIO.h>
3
- #include "ruby.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
- }
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
+ }
@@ -1,4 +1,4 @@
1
- /* $Id: libxml.c 666 2008-12-07 00:16:50Z cfis $ */
1
+ /* $Id: libxml.c 684 2008-12-13 00:34:28Z cfis $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -858,6 +858,7 @@ void Init_libxml_ruby(void)
858
858
  ruby_init_xml_namespaces();
859
859
  ruby_init_xml_namespace();
860
860
  ruby_init_xml_sax_parser();
861
+ ruby_init_xml_sax2_handler();
861
862
  ruby_init_xml_xinclude();
862
863
  ruby_init_xml_xpath();
863
864
  ruby_init_xml_xpath_context();
@@ -71,6 +71,7 @@
71
71
  #include "ruby_xml_namespaces.h"
72
72
  #include "ruby_xml_parser.h"
73
73
  #include "ruby_xml_parser_context.h"
74
+ #include "ruby_xml_sax2_handler.h"
74
75
  #include "ruby_xml_sax_parser.h"
75
76
  #include "ruby_xml_xinclude.h"
76
77
  #include "ruby_xml_xpath.h"
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_document.c 671 2008-12-08 06:06:10Z cfis $ */
1
+ /* $Id: ruby_xml_document.c 688 2008-12-13 01:23:01Z cfis $ */
2
2
 
3
3
  /*
4
4
  * Document-class: LibXML::XML::Document
@@ -527,14 +527,12 @@ static VALUE rxml_document_root_set(VALUE self, VALUE node)
527
527
  * XML::Input encoding constants. */
528
528
  static VALUE rxml_document_save(int argc, VALUE *argv, VALUE self)
529
529
  {
530
- VALUE result;
531
530
  VALUE options = Qnil;
532
531
  VALUE filename = Qnil;
533
532
  xmlDocPtr xdoc;
534
533
  int indent = 1;
535
534
  const char *xfilename;
536
535
  const char *encoding;
537
- xmlChar *buffer;
538
536
  int length;
539
537
 
540
538
  rb_scan_args(argc, argv, "11", &filename, &options);
@@ -563,8 +561,8 @@ static VALUE rxml_document_save(int argc, VALUE *argv, VALUE self)
563
561
 
564
562
  if (length == -1)
565
563
  rxml_raise(&xmlLastError);
566
- else
567
- return (INT2NUM(length));
564
+
565
+ return (INT2NUM(length));
568
566
  }
569
567
 
570
568
  /*
@@ -1,11 +1,11 @@
1
1
  #include "ruby_libxml.h"
2
- #include "ruby_xml_dtd.h"
3
- #include "ruby_xml_error.h"
4
2
 
5
3
  #include <libxml/xmlerror.h>
6
4
 
7
5
  VALUE eXMLError;
6
+ static ID CALL_METHOD;
8
7
  static ID ERROR_HANDLER_ID;
8
+ static ID ON_ERROR_METHOD;
9
9
 
10
10
  /*
11
11
  * Document-class: LibXML::XML::Error
@@ -78,7 +78,7 @@ static VALUE rxml_error_reset_handler(VALUE self)
78
78
  return self;
79
79
  }
80
80
 
81
- static VALUE rxml_error_wrap(xmlErrorPtr xerror)
81
+ VALUE rxml_error_wrap(xmlErrorPtr xerror)
82
82
  {
83
83
  VALUE result = Qnil;
84
84
  if (xerror->message)
@@ -120,16 +120,43 @@ static VALUE rxml_error_wrap(xmlErrorPtr xerror)
120
120
  /* Hook that receives xml error message */
121
121
  static void structuredErrorFunc(void *userData, xmlErrorPtr xerror)
122
122
  {
123
+ VALUE error = rxml_error_wrap(xerror);
124
+
123
125
  /* Wrap error up as Ruby object and send it off to ruby */
124
126
  VALUE block = rb_cvar_get(eXMLError, ERROR_HANDLER_ID);
125
127
 
128
+ /* This next bit of code is a total hack to get around a bug
129
+ in libxml which causes error handlers on sax handlers to
130
+ be ignored in favor of the global handler. In addition,
131
+ the correct context is also not passed in. So try to
132
+ dig it out. */
133
+ if (!userData && xerror->ctxt)
134
+ {
135
+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) xerror->ctxt;
136
+ if (ctxt != ctxt->userData)
137
+ userData = ctxt->userData;
138
+ }
139
+
140
+ /* If the target has an on_error method call it. This
141
+ gets around a bug in libxml where a sax's structured
142
+ error handler is overriden by the global error handler. */
143
+ if (userData)
144
+ {
145
+ VALUE target = (VALUE) userData;
146
+ if (!NIL_P(target) && rb_respond_to(target, ON_ERROR_METHOD))
147
+ {
148
+ rb_funcall(target, ON_ERROR_METHOD, 1, error);
149
+ }
150
+ }
151
+
152
+ /* Now call global handler */
126
153
  if (block != Qnil)
127
154
  {
128
- VALUE error = rxml_error_wrap(xerror);
129
- rb_funcall(block, rb_intern("call"), 1, error);
155
+ rb_funcall(block, CALL_METHOD, 1, error);
130
156
  }
131
157
  }
132
158
 
159
+
133
160
  // Rdoc needs to know
134
161
  #ifdef RDOC_NEVER_DEFINED
135
162
  mLibXML = rb_define_module("LibXML");
@@ -150,11 +177,12 @@ void ruby_init_xml_error()
150
177
 
151
178
  /* Error class */
152
179
  eXMLError = rb_define_class_under(mXML, "Error", rb_eStandardError);
153
- rb_define_singleton_method(eXMLError, "set_handler", rxml_error_set_handler,
154
- 0);
155
- rb_define_singleton_method(eXMLError, "reset_handler",
156
- rxml_error_reset_handler, 0);
180
+ rb_define_singleton_method(eXMLError, "set_handler", rxml_error_set_handler, 0);
181
+ rb_define_singleton_method(eXMLError, "reset_handler", rxml_error_reset_handler, 0);
157
182
 
183
+ ON_ERROR_METHOD = rb_intern("on_error");
184
+ CALL_METHOD = rb_intern("call");
185
+
158
186
  /* Ruby callback to receive errors - set it to nil by default. */
159
187
  ERROR_HANDLER_ID = rb_intern("@@__error_handler_callback__");
160
188
  rxml_set_handler(eXMLError, Qnil);
@@ -8,6 +8,7 @@
8
8
  extern VALUE eXMLError;
9
9
 
10
10
  void ruby_init_xml_error();
11
+ VALUE rxml_error_wrap(xmlErrorPtr xerror);
11
12
  void rxml_raise(xmlErrorPtr xerror);
12
13
 
13
14
  #endif
@@ -1,158 +1,158 @@
1
- /* $Id: ruby_xml_namespace.c 671 2008-12-08 06:06:10Z cfis $ */
2
-
3
- /* Please see the LICENSE file for copyright and distribution information */
4
-
5
- #include "ruby_libxml.h"
6
- #include "ruby_xml_namespace.h"
7
-
8
- VALUE cXMLNamespace;
9
-
10
- /* Document-class: LibXML::XML::Namespace
11
- *
12
- * The Namespace class represents an XML namespace.
13
- * To add a namespace to a node, create a new instance
14
- * of this class. Note that this does *not* assign the
15
- * node to the namespace. To do that see the
16
- * XML::Namespaces#namespace method.
17
- *
18
- * Usage:
19
- *
20
- * node = XML::Node.new('<Envelope>')
21
- * XML::Namespace.new(node, 'soap', 'http://schemas.xmlsoap.org/soap/envelope/')
22
- * assert_equal("<Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"/>", node.to_s)
23
- * assert_nil(node.namespaces.namespace)
24
- */
25
-
26
- static VALUE rxml_namespace_free(xmlNsPtr xns)
27
- {
28
- xns->_private = NULL;
29
- }
30
-
31
- static VALUE rxml_namespace_alloc(VALUE klass)
32
- {
33
- return Data_Wrap_Struct(klass, NULL, rxml_namespace_free, NULL);
34
- }
35
-
36
- /*
37
- * call-seq:
38
- * initialize(node, "prefix", "href") -> XML::Namespace
39
- *
40
- * Create a new namespace and adds it to the specified node.
41
- * Note this does *not* assign the node to the namespace.
42
- * To do that see the XML::Namespaces#namespace method.
43
- */
44
- static VALUE rxml_namespace_initialize(VALUE self, VALUE node, VALUE prefix,
45
- VALUE href)
46
- {
47
- xmlNodePtr xnode;
48
- xmlChar *xmlPrefix;
49
- xmlNsPtr xns;
50
-
51
- Check_Type(node, T_DATA);
52
- Data_Get_Struct(node, xmlNode, xnode);
53
-
54
- /* Prefix can be null - that means its the default namespace */
55
- xmlPrefix = NIL_P(prefix) ? NULL : (xmlChar *)StringValuePtr(prefix);
56
- xns = xmlNewNs(xnode, (xmlChar*) StringValuePtr(href), xmlPrefix);
57
-
58
- if (!xns)
59
- rxml_raise(&xmlLastError);
60
-
61
- xns->_private = (void*)self;
62
- DATA_PTR(self) = xns;
63
- return self;
64
- }
65
-
66
- VALUE rxml_namespace_wrap(xmlNsPtr xns)
67
- {
68
- if (xns->_private)
69
- {
70
- return (VALUE)xns->_private;
71
- }
72
- else
73
- {
74
- VALUE ns = Data_Wrap_Struct(cXMLNamespace, NULL, rxml_namespace_free, xns);
75
- xns->_private = (void*)ns;
76
- return ns;
77
- }
78
- }
79
-
80
- /*
81
- * call-seq:
82
- * ns.href -> "href"
83
- *
84
- * Usage:
85
- *
86
- * doc = XML::Document.string('<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"/>')
87
- * ns = doc.root.namespaces.find_by_href('http://schemas.xmlsoap.org/soap/envelope/')
88
- * assert_equal('http://schemas.xmlsoap.org/soap/envelope/', ns.href)
89
- */
90
- static VALUE rxml_namespace_href_get(VALUE self)
91
- {
92
- xmlNsPtr xns;
93
- Data_Get_Struct(self, xmlNs, xns);
94
- if (xns == NULL || xns->href == NULL)
95
- return (Qnil);
96
- else
97
- return (rb_str_new2((const char*) xns->href));
98
- }
99
-
100
- /*
101
- * call-seq:
102
- * ns.prefix -> "prefix"
103
- *
104
- * Obtain the namespace's prefix.
105
- *
106
- * Usage:
107
- *
108
- * doc = XML::Document.string('<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"/>')
109
- * ns = doc.root.namespaces.find_by_href('http://schemas.xmlsoap.org/soap/envelope/')
110
- * assert_equal('soap', ns.prefix)
111
- */
112
- static VALUE rxml_namespace_prefix_get(VALUE self)
113
- {
114
- xmlNsPtr xns;
115
- Data_Get_Struct(self, xmlNs, xns);
116
- if (xns == NULL || xns->prefix == NULL)
117
- return (Qnil);
118
- else
119
- return (rb_str_new2((const char*) xns->prefix));
120
- }
121
-
122
- /*
123
- * call-seq:
124
- * ns.next -> XML::Namespace
125
- *
126
- * Obtain the next namespace.
127
- *
128
- * Usage:
129
- *
130
- * doc = XML::Document.string('<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"/>')
131
- * ns = doc.root.namespaces.find_by_href('http://schemas.xmlsoap.org/soap/envelope/')
132
- * assert_nil(ns.next)
133
- */
134
- static VALUE rxml_namespace_next(VALUE self)
135
- {
136
- xmlNsPtr xns;
137
- Data_Get_Struct(self, xmlNs, xns);
138
- if (xns == NULL || xns->next == NULL)
139
- return (Qnil);
140
- else
141
- return (rxml_namespace_wrap(xns->next));
142
- }
143
-
144
- // Rdoc needs to know
145
- #ifdef RDOC_NEVER_DEFINED
146
- mLibXML = rb_define_module("LibXML");
147
- mXML = rb_define_module_under(mLibXML, "XML");
148
- #endif
149
-
150
- void ruby_init_xml_namespace(void)
151
- {
152
- cXMLNamespace = rb_define_class_under(mXML, "Namespace", rb_cObject);
153
- rb_define_alloc_func(cXMLNamespace, rxml_namespace_alloc);
154
- rb_define_method(cXMLNamespace, "initialize", rxml_namespace_initialize, 3);
155
- rb_define_method(cXMLNamespace, "href", rxml_namespace_href_get, 0);
156
- rb_define_method(cXMLNamespace, "next", rxml_namespace_next, 0);
157
- rb_define_method(cXMLNamespace, "prefix", rxml_namespace_prefix_get, 0);
158
- }
1
+ /* $Id: ruby_xml_namespace.c 685 2008-12-13 01:13:56Z cfis $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ #include "ruby_libxml.h"
6
+ #include "ruby_xml_namespace.h"
7
+
8
+ VALUE cXMLNamespace;
9
+
10
+ /* Document-class: LibXML::XML::Namespace
11
+ *
12
+ * The Namespace class represents an XML namespace.
13
+ * To add a namespace to a node, create a new instance
14
+ * of this class. Note that this does *not* assign the
15
+ * node to the namespace. To do that see the
16
+ * XML::Namespaces#namespace method.
17
+ *
18
+ * Usage:
19
+ *
20
+ * node = XML::Node.new('<Envelope>')
21
+ * XML::Namespace.new(node, 'soap', 'http://schemas.xmlsoap.org/soap/envelope/')
22
+ * assert_equal("<Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"/>", node.to_s)
23
+ * assert_nil(node.namespaces.namespace)
24
+ */
25
+
26
+ static void rxml_namespace_free(xmlNsPtr xns)
27
+ {
28
+ xns->_private = NULL;
29
+ }
30
+
31
+ static VALUE rxml_namespace_alloc(VALUE klass)
32
+ {
33
+ return Data_Wrap_Struct(klass, NULL, rxml_namespace_free, NULL);
34
+ }
35
+
36
+ /*
37
+ * call-seq:
38
+ * initialize(node, "prefix", "href") -> XML::Namespace
39
+ *
40
+ * Create a new namespace and adds it to the specified node.
41
+ * Note this does *not* assign the node to the namespace.
42
+ * To do that see the XML::Namespaces#namespace method.
43
+ */
44
+ static VALUE rxml_namespace_initialize(VALUE self, VALUE node, VALUE prefix,
45
+ VALUE href)
46
+ {
47
+ xmlNodePtr xnode;
48
+ xmlChar *xmlPrefix;
49
+ xmlNsPtr xns;
50
+
51
+ Check_Type(node, T_DATA);
52
+ Data_Get_Struct(node, xmlNode, xnode);
53
+
54
+ /* Prefix can be null - that means its the default namespace */
55
+ xmlPrefix = NIL_P(prefix) ? NULL : (xmlChar *)StringValuePtr(prefix);
56
+ xns = xmlNewNs(xnode, (xmlChar*) StringValuePtr(href), xmlPrefix);
57
+
58
+ if (!xns)
59
+ rxml_raise(&xmlLastError);
60
+
61
+ xns->_private = (void*)self;
62
+ DATA_PTR(self) = xns;
63
+ return self;
64
+ }
65
+
66
+ VALUE rxml_namespace_wrap(xmlNsPtr xns)
67
+ {
68
+ if (xns->_private)
69
+ {
70
+ return (VALUE)xns->_private;
71
+ }
72
+ else
73
+ {
74
+ VALUE ns = Data_Wrap_Struct(cXMLNamespace, NULL, rxml_namespace_free, xns);
75
+ xns->_private = (void*)ns;
76
+ return ns;
77
+ }
78
+ }
79
+
80
+ /*
81
+ * call-seq:
82
+ * ns.href -> "href"
83
+ *
84
+ * Usage:
85
+ *
86
+ * doc = XML::Document.string('<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"/>')
87
+ * ns = doc.root.namespaces.find_by_href('http://schemas.xmlsoap.org/soap/envelope/')
88
+ * assert_equal('http://schemas.xmlsoap.org/soap/envelope/', ns.href)
89
+ */
90
+ static VALUE rxml_namespace_href_get(VALUE self)
91
+ {
92
+ xmlNsPtr xns;
93
+ Data_Get_Struct(self, xmlNs, xns);
94
+ if (xns->href == NULL)
95
+ return Qnil;
96
+ else
97
+ return rb_str_new2((const char*) xns->href);
98
+ }
99
+
100
+ /*
101
+ * call-seq:
102
+ * ns.prefix -> "prefix"
103
+ *
104
+ * Obtain the namespace's prefix.
105
+ *
106
+ * Usage:
107
+ *
108
+ * doc = XML::Document.string('<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"/>')
109
+ * ns = doc.root.namespaces.find_by_href('http://schemas.xmlsoap.org/soap/envelope/')
110
+ * assert_equal('soap', ns.prefix)
111
+ */
112
+ static VALUE rxml_namespace_prefix_get(VALUE self)
113
+ {
114
+ xmlNsPtr xns;
115
+ Data_Get_Struct(self, xmlNs, xns);
116
+ if (xns->prefix == NULL)
117
+ return Qnil;
118
+ else
119
+ return rb_str_new2((const char*) xns->prefix);
120
+ }
121
+
122
+ /*
123
+ * call-seq:
124
+ * ns.next -> XML::Namespace
125
+ *
126
+ * Obtain the next namespace.
127
+ *
128
+ * Usage:
129
+ *
130
+ * doc = XML::Document.string('<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"/>')
131
+ * ns = doc.root.namespaces.find_by_href('http://schemas.xmlsoap.org/soap/envelope/')
132
+ * assert_nil(ns.next)
133
+ */
134
+ static VALUE rxml_namespace_next(VALUE self)
135
+ {
136
+ xmlNsPtr xns;
137
+ Data_Get_Struct(self, xmlNs, xns);
138
+ if (xns == NULL || xns->next == NULL)
139
+ return (Qnil);
140
+ else
141
+ return (rxml_namespace_wrap(xns->next));
142
+ }
143
+
144
+ // Rdoc needs to know
145
+ #ifdef RDOC_NEVER_DEFINED
146
+ mLibXML = rb_define_module("LibXML");
147
+ mXML = rb_define_module_under(mLibXML, "XML");
148
+ #endif
149
+
150
+ void ruby_init_xml_namespace(void)
151
+ {
152
+ cXMLNamespace = rb_define_class_under(mXML, "Namespace", rb_cObject);
153
+ rb_define_alloc_func(cXMLNamespace, rxml_namespace_alloc);
154
+ rb_define_method(cXMLNamespace, "initialize", rxml_namespace_initialize, 3);
155
+ rb_define_method(cXMLNamespace, "href", rxml_namespace_href_get, 0);
156
+ rb_define_method(cXMLNamespace, "next", rxml_namespace_next, 0);
157
+ rb_define_method(cXMLNamespace, "prefix", rxml_namespace_prefix_get, 0);
158
+ }