libxml-ruby 1.1.3 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. data/CHANGES +1 -1
  2. data/LICENSE +22 -22
  3. data/README +160 -160
  4. data/Rakefile +0 -9
  5. data/ext/libxml/Makefile +156 -0
  6. data/ext/libxml/extconf.h +5 -0
  7. data/ext/libxml/extconf.rb +4 -160
  8. data/ext/libxml/libxml-ruby.so.a +0 -0
  9. data/ext/libxml/libxml.o +0 -0
  10. data/ext/libxml/libxml_ruby.so +0 -0
  11. data/ext/libxml/mkmf.log +129 -0
  12. data/ext/libxml/ruby_xml.o +0 -0
  13. data/ext/libxml/ruby_xml_attr.c +1 -1
  14. data/ext/libxml/ruby_xml_attr.h +1 -1
  15. data/ext/libxml/ruby_xml_attr.o +0 -0
  16. data/ext/libxml/ruby_xml_attr_decl.o +0 -0
  17. data/ext/libxml/ruby_xml_attributes.o +0 -0
  18. data/ext/libxml/ruby_xml_cbg.o +0 -0
  19. data/ext/libxml/ruby_xml_document.c +936 -936
  20. data/ext/libxml/ruby_xml_document.h +1 -1
  21. data/ext/libxml/ruby_xml_document.o +0 -0
  22. data/ext/libxml/ruby_xml_dtd.o +0 -0
  23. data/ext/libxml/ruby_xml_encoding.o +0 -0
  24. data/ext/libxml/ruby_xml_error.o +0 -0
  25. data/ext/libxml/ruby_xml_html_parser.c +1 -1
  26. data/ext/libxml/ruby_xml_html_parser.h +1 -1
  27. data/ext/libxml/ruby_xml_html_parser.o +0 -0
  28. data/ext/libxml/ruby_xml_html_parser_context.o +0 -0
  29. data/ext/libxml/ruby_xml_html_parser_options.o +0 -0
  30. data/ext/libxml/ruby_xml_input_cbg.o +0 -0
  31. data/ext/libxml/ruby_xml_io.o +0 -0
  32. data/ext/libxml/ruby_xml_namespace.c +1 -1
  33. data/ext/libxml/ruby_xml_namespace.h +1 -1
  34. data/ext/libxml/ruby_xml_namespace.o +0 -0
  35. data/ext/libxml/ruby_xml_namespaces.o +0 -0
  36. data/ext/libxml/ruby_xml_node.c +1386 -1386
  37. data/ext/libxml/ruby_xml_node.h +1 -1
  38. data/ext/libxml/ruby_xml_node.o +0 -0
  39. data/ext/libxml/ruby_xml_parser.c +1 -1
  40. data/ext/libxml/ruby_xml_parser.h +1 -1
  41. data/ext/libxml/ruby_xml_parser.o +0 -0
  42. data/ext/libxml/ruby_xml_parser_context.c +1 -1
  43. data/ext/libxml/ruby_xml_parser_context.h +1 -1
  44. data/ext/libxml/ruby_xml_parser_context.o +0 -0
  45. data/ext/libxml/ruby_xml_parser_options.o +0 -0
  46. data/ext/libxml/ruby_xml_reader.o +0 -0
  47. data/ext/libxml/ruby_xml_relaxng.o +0 -0
  48. data/ext/libxml/ruby_xml_sax2_handler.o +0 -0
  49. data/ext/libxml/ruby_xml_sax_parser.c +1 -1
  50. data/ext/libxml/ruby_xml_sax_parser.h +1 -1
  51. data/ext/libxml/ruby_xml_sax_parser.o +0 -0
  52. data/ext/libxml/ruby_xml_schema.o +0 -0
  53. data/ext/libxml/ruby_xml_version.h +3 -3
  54. data/ext/libxml/ruby_xml_xinclude.c +1 -1
  55. data/ext/libxml/ruby_xml_xinclude.h +1 -1
  56. data/ext/libxml/ruby_xml_xinclude.o +0 -0
  57. data/ext/libxml/ruby_xml_xpath.c +1 -1
  58. data/ext/libxml/ruby_xml_xpath.h +1 -1
  59. data/ext/libxml/ruby_xml_xpath.o +0 -0
  60. data/ext/libxml/ruby_xml_xpath_context.c +1 -1
  61. data/ext/libxml/ruby_xml_xpath_context.h +1 -1
  62. data/ext/libxml/ruby_xml_xpath_context.o +0 -0
  63. data/ext/libxml/ruby_xml_xpath_expression.o +0 -0
  64. data/ext/libxml/ruby_xml_xpath_object.o +0 -0
  65. data/ext/libxml/ruby_xml_xpointer.c +1 -1
  66. data/ext/libxml/ruby_xml_xpointer.h +1 -1
  67. data/ext/libxml/ruby_xml_xpointer.o +0 -0
  68. data/ext/mingw/build.rake +3 -3
  69. data/lib/libxml.rb +29 -29
  70. data/test/model/merge_bug_data.xml +58 -58
  71. data/test/model/rubynet.xml +79 -79
  72. data/test/model/xinclude.xml +4 -4
  73. data/test/tc_attr.rb +170 -170
  74. data/test/tc_document.rb +113 -113
  75. data/test/tc_document_write.rb +117 -117
  76. data/test/tc_dtd.rb +123 -123
  77. data/test/tc_html_parser.rb +137 -137
  78. data/test/tc_node.rb +180 -180
  79. data/test/tc_node_cdata.rb +49 -49
  80. data/test/tc_node_comment.rb +30 -30
  81. data/test/tc_node_edit.rb +157 -157
  82. data/test/tc_node_xlink.rb +26 -26
  83. data/test/tc_parser.rb +329 -329
  84. data/test/tc_parser_context.rb +185 -185
  85. data/test/tc_reader.rb +283 -283
  86. data/test/tc_sax_parser.rb +273 -273
  87. data/test/tc_schema.rb +51 -51
  88. data/test/tc_xinclude.rb +19 -19
  89. data/test/tc_xpath.rb +193 -193
  90. data/test/tc_xpointer.rb +72 -72
  91. metadata +55 -14
  92. data/ext/libxml/build.log +0 -4
@@ -0,0 +1,5 @@
1
+ #ifndef EXTCONF_H
2
+ #define EXTCONF_H
3
+ #define HAVE_ZLIB_H 1
4
+ #define HAVE_LIBXML_XMLVERSION_H 1
5
+ #endif
@@ -91,16 +91,13 @@ else
91
91
  dir_config('xml2')
92
92
  end
93
93
 
94
- unless (cflags and libs) or
95
- (have_library('xml2', 'xmlParseDoc') or
94
+ unless (have_library('xml2', 'xmlParseDoc') or
96
95
  have_library('libxml2', 'xmlParseDoc') or
97
96
  find_library('xml2', 'xmlParseDoc', '/opt/lib', '/usr/local/lib', '/usr/lib')) and
98
97
  (have_header('libxml/xmlversion.h') or
99
- find_header('libxml/xmlversion.h',
100
- "#{CONFIG['prefix']}/include",
101
- "#{CONFIG['prefix']}/include/libxml2",
98
+ find_header('libxml/xmlversion.h',
102
99
  '/opt/include/libxml2',
103
- '/usr/local/include/libxml2',
100
+ '/usr/local/include/libxml2',
104
101
  '/usr/include/libxml2'))
105
102
  crash(<<EOL)
106
103
  need libxml2.
@@ -118,161 +115,8 @@ end
118
115
  $INCFLAGS << " -I/usr/local/include"
119
116
 
120
117
  $CFLAGS << ' ' << $INCFLAGS
118
+
121
119
  #$INSTALLFILES = [["libxml.rb", "$(RUBYLIBDIR)", "../xml"]]
122
120
 
123
121
  create_header()
124
122
  create_makefile('libxml_ruby')
125
-
126
- __END__
127
-
128
- SHELL = /bin/sh
129
-
130
- #### Start of system configuration section. ####
131
-
132
- # I think we can remove all the parts related to the install target
133
- # since setup.rb and RubyGems handles that on their own. Correct?
134
-
135
- srcdir = .
136
- topdir = #{archdir} #/usr/lib/ruby/1.8/x86_64-linux
137
- hdrdir = $(topdir)
138
- VPATH = $(srcdir):$(topdir):$(hdrdir)
139
- prefix = $(DESTDIR)/usr
140
- exec_prefix = $(DESTDIR)/usr
141
- sitedir = $(DESTDIR)/usr/local/lib/site_ruby
142
- rubylibdir = $(libdir)/ruby/$(ruby_version)
143
- docdir = $(datarootdir)/doc/$(PACKAGE)
144
- dvidir = $(docdir)
145
- datarootdir = $(prefix)/share
146
- archdir = $(rubylibdir)/$(arch)
147
- sbindir = $(exec_prefix)/sbin
148
- psdir = $(docdir)
149
- localedir = $(datarootdir)/locale
150
- htmldir = $(docdir)
151
- datadir = $(datarootdir)
152
- includedir = $(prefix)/include
153
- infodir = $(prefix)/share/info
154
- sysconfdir = $(DESTDIR)/etc
155
- mandir = $(prefix)/share/man
156
- libdir = $(DESTDIR)/usr/lib
157
- sharedstatedir = $(prefix)/com
158
- oldincludedir = $(DESTDIR)/usr/include
159
- pdfdir = $(docdir)
160
- sitearchdir = $(sitelibdir)/$(sitearch)
161
- bindir = $(exec_prefix)/bin
162
- localstatedir = $(DESTDIR)/var
163
- sitelibdir = $(sitedir)/$(ruby_version)
164
- libexecdir = $(prefix)/lib/ruby1.8
165
-
166
- CC = cc
167
- LIBRUBY = $(LIBRUBY_SO)
168
- LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
169
- LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
170
- LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
171
-
172
- RUBY_EXTCONF_H = extconf.h
173
- CFLAGS = -fPIC -fno-strict-aliasing -g -O2 -fPIC -I. -I/usr/lib/ruby/1.8/x86_64-linux -I. -I/usr/include/libxml2
174
- INCFLAGS = -I. -I. -I/usr/lib/ruby/1.8/x86_64-linux -I. -I/usr/include/libxml2
175
- CPPFLAGS = -DRUBY_EXTCONF_H=\"$(RUBY_EXTCONF_H)\"
176
- CXXFLAGS = $(CFLAGS)
177
- DLDFLAGS = -L. -rdynamic -Wl,-export-dynamic
178
- LDSHARED = $(CC) -shared
179
- AR = ar
180
- EXEEXT =
181
-
182
- RUBY_INSTALL_NAME = ruby1.8
183
- RUBY_SO_NAME = ruby1.8
184
- arch = x86_64-linux
185
- sitearch = x86_64-linux
186
- ruby_version = 1.8
187
- ruby = /usr/bin/ruby1.8
188
- RUBY = $(ruby)
189
- RM = rm -f
190
- MAKEDIRS = mkdir -p
191
- INSTALL = /usr/bin/install -c
192
- INSTALL_PROG = $(INSTALL) -m 0755
193
- INSTALL_DATA = $(INSTALL) -m 644
194
- COPY = cp
195
-
196
- preload =
197
-
198
- libpath = . $(libdir) /usr/lib
199
- LIBPATH = -L"." -L"$(libdir)" -L"/usr/lib"
200
- DEFFILE =
201
-
202
- CLEANFILES =
203
- DISTCLEANFILES =
204
-
205
- extout =
206
- extout_prefix =
207
- target_prefix = /xml
208
- LOCAL_LIBS =
209
- LIBS = $(LIBRUBYARG_SHARED) -lxml2 -lc -lz -lm -lnsl -lpthread -ldl -lcrypt -lm -lc
210
-
211
- SRCS = #{srcs.join(' ')}
212
- OBJS = #{objs.join(' ')}
213
-
214
- TARGET = #{target}
215
- DLLIB = $(TARGET).so
216
- EXTSTATIC =
217
- STATIC_LIB =
218
-
219
- RUBYCOMMONDIR = $(sitedir)$(target_prefix)
220
- RUBYLIBDIR = $(sitelibdir)$(target_prefix)
221
- RUBYARCHDIR = $(sitearchdir)$(target_prefix)
222
-
223
- TARGET_SO = $(DLLIB)
224
- CLEANLIBS = $(TARGET).so $(TARGET).il? $(TARGET).tds $(TARGET).map
225
- CLEANOBJS = *.o *.a *.s[ol] *.pdb *.exp *.bak
226
-
227
- all: $(DLLIB)
228
- static: $(STATIC_LIB)
229
-
230
- clean:
231
- @-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
232
-
233
- distclean: clean
234
- @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
235
- @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
236
-
237
- realclean: distclean
238
- install: install-so install-rb
239
-
240
- install-so: $(RUBYARCHDIR)
241
- install-so: $(RUBYARCHDIR)/$(DLLIB)
242
- $(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
243
- $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
244
- install-rb: pre-install-rb install-rb-default
245
- install-rb-default: pre-install-rb-default
246
- pre-install-rb: Makefile
247
- pre-install-rb-default: Makefile
248
- $(RUBYARCHDIR):
249
- $(MAKEDIRS) $@
250
-
251
- site-install: site-install-so site-install-rb
252
- site-install-so: install-so
253
- site-install-rb: install-rb
254
-
255
- .SUFFIXES: .c .m .cc .cxx .cpp .C .o
256
-
257
- .cc.o:
258
- $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
259
-
260
- .cxx.o:
261
- $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
262
-
263
- .cpp.o:
264
- $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
265
-
266
- .C.o:
267
- $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
268
-
269
- .c.o:
270
- $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<
271
-
272
- $(DLLIB): $(OBJS)
273
- @-$(RM) $@
274
- $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
275
-
276
-
277
- $(OBJS): ruby.h defines.h $(RUBY_EXTCONF_H)
278
-
Binary file
Binary file
@@ -0,0 +1,129 @@
1
+ have_library: checking for socket() in socket.lib... -------------------- no
2
+
3
+ "cl -nologo -Feconftest -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -MD -Zi -O2b2xg- -G6 conftest.c msvcrt-ruby18-static.lib socket.lib oldnames.lib user32.lib advapi32.lib shell32.lib ws2_32.lib -link -libpath:"." -libpath:"C:/Development/Ruby/lib" -libpath:"C:/Development/Ruby/lib" -stack:0x2000000"
4
+ checked program was:
5
+ /* begin */
6
+ 1: #define WIN32_LEAN_AND_MEAN
7
+ 2: #define WIN32
8
+ 3: #include <winsock2.h>
9
+ 4: #include <windows.h>
10
+ 5:
11
+ 6: /*top*/
12
+ 7: int main() { return 0; }
13
+ 8: int t() { void ((*volatile p)()); p = (void ((*)()))socket; return 0; }
14
+ /* end */
15
+
16
+ "cl -nologo -Feconftest -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -MD -Zi -O2b2xg- -G6 conftest.c msvcrt-ruby18-static.lib socket.lib oldnames.lib user32.lib advapi32.lib shell32.lib ws2_32.lib -link -libpath:"." -libpath:"C:/Development/Ruby/lib" -libpath:"C:/Development/Ruby/lib" -stack:0x2000000"
17
+ checked program was:
18
+ /* begin */
19
+ 1: /*top*/
20
+ 2: int main() { return 0; }
21
+ 3: int t() { socket(); return 0; }
22
+ /* end */
23
+
24
+ --------------------
25
+
26
+ have_library: checking for gethostbyname() in nsl.lib... -------------------- no
27
+
28
+ "cl -nologo -Feconftest -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -MD -Zi -O2b2xg- -G6 conftest.c msvcrt-ruby18-static.lib nsl.lib oldnames.lib user32.lib advapi32.lib shell32.lib ws2_32.lib -link -libpath:"." -libpath:"C:/Development/Ruby/lib" -libpath:"C:/Development/Ruby/lib" -stack:0x2000000"
29
+ checked program was:
30
+ /* begin */
31
+ 1: #define WIN32_LEAN_AND_MEAN
32
+ 2: #define WIN32
33
+ 3: #include <winsock2.h>
34
+ 4: #include <windows.h>
35
+ 5:
36
+ 6: /*top*/
37
+ 7: int main() { return 0; }
38
+ 8: int t() { void ((*volatile p)()); p = (void ((*)()))gethostbyname; return 0; }
39
+ /* end */
40
+
41
+ "cl -nologo -Feconftest -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -MD -Zi -O2b2xg- -G6 conftest.c msvcrt-ruby18-static.lib nsl.lib oldnames.lib user32.lib advapi32.lib shell32.lib ws2_32.lib -link -libpath:"." -libpath:"C:/Development/Ruby/lib" -libpath:"C:/Development/Ruby/lib" -stack:0x2000000"
42
+ checked program was:
43
+ /* begin */
44
+ 1: /*top*/
45
+ 2: int main() { return 0; }
46
+ 3: int t() { gethostbyname(); return 0; }
47
+ /* end */
48
+
49
+ --------------------
50
+
51
+ have_library: checking for atan() in m.lib... -------------------- yes
52
+
53
+ --------------------
54
+
55
+ have_library: checking for inflate() in z.lib... -------------------- no
56
+
57
+ "cl -nologo -Feconftest -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -MD -Zi -O2b2xg- -G6 conftest.c msvcrt-ruby18-static.lib z.lib oldnames.lib user32.lib advapi32.lib shell32.lib ws2_32.lib -link -libpath:"." -libpath:"C:/Development/Ruby/lib" -libpath:"C:/Development/Ruby/lib" -stack:0x2000000"
58
+ checked program was:
59
+ /* begin */
60
+ 1: #define WIN32_LEAN_AND_MEAN
61
+ 2: #define WIN32
62
+ 3: #include <winsock2.h>
63
+ 4: #include <windows.h>
64
+ 5:
65
+ 6: /*top*/
66
+ 7: int main() { return 0; }
67
+ 8: int t() { void ((*volatile p)()); p = (void ((*)()))inflate; return 0; }
68
+ /* end */
69
+
70
+ "cl -nologo -Feconftest -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -MD -Zi -O2b2xg- -G6 conftest.c msvcrt-ruby18-static.lib z.lib oldnames.lib user32.lib advapi32.lib shell32.lib ws2_32.lib -link -libpath:"." -libpath:"C:/Development/Ruby/lib" -libpath:"C:/Development/Ruby/lib" -stack:0x2000000"
71
+ checked program was:
72
+ /* begin */
73
+ 1: /*top*/
74
+ 2: int main() { return 0; }
75
+ 3: int t() { inflate(); return 0; }
76
+ /* end */
77
+
78
+ --------------------
79
+
80
+ have_library: checking for inflate() in zlib.lib... -------------------- no
81
+
82
+ "cl -nologo -Feconftest -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -MD -Zi -O2b2xg- -G6 conftest.c msvcrt-ruby18-static.lib zlib.lib oldnames.lib user32.lib advapi32.lib shell32.lib ws2_32.lib -link -libpath:"." -libpath:"C:/Development/Ruby/lib" -libpath:"C:/Development/Ruby/lib" -stack:0x2000000"
83
+ checked program was:
84
+ /* begin */
85
+ 1: #define WIN32_LEAN_AND_MEAN
86
+ 2: #define WIN32
87
+ 3: #include <winsock2.h>
88
+ 4: #include <windows.h>
89
+ 5:
90
+ 6: /*top*/
91
+ 7: int main() { return 0; }
92
+ 8: int t() { void ((*volatile p)()); p = (void ((*)()))inflate; return 0; }
93
+ /* end */
94
+
95
+ "cl -nologo -Feconftest -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -MD -Zi -O2b2xg- -G6 conftest.c msvcrt-ruby18-static.lib zlib.lib oldnames.lib user32.lib advapi32.lib shell32.lib ws2_32.lib -link -libpath:"." -libpath:"C:/Development/Ruby/lib" -libpath:"C:/Development/Ruby/lib" -stack:0x2000000"
96
+ checked program was:
97
+ /* begin */
98
+ 1: /*top*/
99
+ 2: int main() { return 0; }
100
+ 3: int t() { inflate(); return 0; }
101
+ /* end */
102
+
103
+ --------------------
104
+
105
+ have_library: checking for inflate() in zlib1.lib... -------------------- no
106
+
107
+ "cl -nologo -Feconftest -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -MD -Zi -O2b2xg- -G6 conftest.c msvcrt-ruby18-static.lib zlib1.lib oldnames.lib user32.lib advapi32.lib shell32.lib ws2_32.lib -link -libpath:"." -libpath:"C:/Development/Ruby/lib" -libpath:"C:/Development/Ruby/lib" -stack:0x2000000"
108
+ checked program was:
109
+ /* begin */
110
+ 1: #define WIN32_LEAN_AND_MEAN
111
+ 2: #define WIN32
112
+ 3: #include <winsock2.h>
113
+ 4: #include <windows.h>
114
+ 5:
115
+ 6: /*top*/
116
+ 7: int main() { return 0; }
117
+ 8: int t() { void ((*volatile p)()); p = (void ((*)()))inflate; return 0; }
118
+ /* end */
119
+
120
+ "cl -nologo -Feconftest -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -I. -IC:/Development/Ruby/lib/ruby/1.8/i386-mswin32 -MD -Zi -O2b2xg- -G6 conftest.c msvcrt-ruby18-static.lib zlib1.lib oldnames.lib user32.lib advapi32.lib shell32.lib ws2_32.lib -link -libpath:"." -libpath:"C:/Development/Ruby/lib" -libpath:"C:/Development/Ruby/lib" -stack:0x2000000"
121
+ checked program was:
122
+ /* begin */
123
+ 1: /*top*/
124
+ 2: int main() { return 0; }
125
+ 3: int t() { inflate(); return 0; }
126
+ /* end */
127
+
128
+ --------------------
129
+
Binary file
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_attr.c 847 2009-03-21 22:19:43Z cfis $ */
1
+ /* $Id$ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_attr.h 758 2009-01-25 20:36:03Z cfis $ */
1
+ /* $Id$ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
Binary file
@@ -1,936 +1,936 @@
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.compression -> num
146
- *
147
- * Obtain this document's compression mode identifier.
148
- */
149
- static VALUE rxml_document_compression_get(VALUE self)
150
- {
151
- #ifdef HAVE_ZLIB_H
152
- xmlDocPtr xdoc;
153
-
154
- int compmode;
155
- Data_Get_Struct(self, xmlDoc, xdoc);
156
-
157
- compmode = xmlGetDocCompressMode(xdoc);
158
- if (compmode == -1)
159
- return(Qnil);
160
- else
161
- return(INT2NUM(compmode));
162
- #else
163
- rb_warn("libxml not compiled with zlib support");
164
- return (Qfalse);
165
- #endif
166
- }
167
-
168
- /*
169
- * call-seq:
170
- * document.compression = num
171
- *
172
- * Set this document's compression mode.
173
- */
174
- static VALUE rxml_document_compression_set(VALUE self, VALUE num)
175
- {
176
- #ifdef HAVE_ZLIB_H
177
- xmlDocPtr xdoc;
178
-
179
- int compmode;
180
- Check_Type(num, T_FIXNUM);
181
- Data_Get_Struct(self, xmlDoc, xdoc);
182
-
183
- if (xdoc == NULL)
184
- {
185
- return(Qnil);
186
- }
187
- else
188
- {
189
- xmlSetDocCompressMode(xdoc, NUM2INT(num));
190
-
191
- compmode = xmlGetDocCompressMode(xdoc);
192
- if (compmode == -1)
193
- return(Qnil);
194
- else
195
- return(INT2NUM(compmode));
196
- }
197
- #else
198
- rb_warn("libxml compiled without zlib support");
199
- return (Qfalse);
200
- #endif
201
- }
202
-
203
- /*
204
- * call-seq:
205
- * document.compression? -> (true|false)
206
- *
207
- * Determine whether this document is compressed.
208
- */
209
- static VALUE rxml_document_compression_q(VALUE self)
210
- {
211
- #ifdef HAVE_ZLIB_H
212
- xmlDocPtr xdoc;
213
-
214
- Data_Get_Struct(self, xmlDoc, xdoc);
215
-
216
- if (xdoc->compression != -1)
217
- return(Qtrue);
218
- else
219
- return(Qfalse);
220
- #else
221
- rb_warn("libxml compiled without zlib support");
222
- return (Qfalse);
223
- #endif
224
- }
225
-
226
- /*
227
- * call-seq:
228
- * document.child -> node
229
- *
230
- * Get this document's child node.
231
- */
232
- static VALUE rxml_document_child_get(VALUE self)
233
- {
234
- xmlDocPtr xdoc;
235
- Data_Get_Struct(self, xmlDoc, xdoc);
236
-
237
- if (xdoc->children == NULL)
238
- return (Qnil);
239
-
240
- return rxml_node_wrap(xdoc->children);
241
- }
242
-
243
- /*
244
- * call-seq:
245
- * document.child? -> (true|false)
246
- *
247
- * Determine whether this document has a child node.
248
- */
249
- static VALUE rxml_document_child_q(VALUE self)
250
- {
251
- xmlDocPtr xdoc;
252
- Data_Get_Struct(self, xmlDoc, xdoc);
253
-
254
- if (xdoc->children == NULL)
255
- return (Qfalse);
256
- else
257
- return (Qtrue);
258
- }
259
-
260
-
261
- /*
262
- * call-seq:
263
- * node.debug -> true|false
264
- *
265
- * Print libxml debugging information to stdout.
266
- * Requires that libxml was compiled with debugging enabled.
267
- */
268
- static VALUE rxml_document_debug(VALUE self)
269
- {
270
- #ifdef LIBXML_DEBUG_ENABLED
271
- xmlDocPtr xdoc;
272
- Data_Get_Struct(self, xmlDoc, xdoc);
273
- xmlDebugDumpDocument(NULL, xdoc);
274
- return Qtrue;
275
- #else
276
- rb_warn("libxml was compiled without debugging support.")
277
- return Qfalse;
278
- #endif
279
- }
280
-
281
- /*
282
- * call-seq:
283
- * document.encoding -> XML::Encoding::UTF_8
284
- *
285
- * Obtain the encoding specified by this document.
286
- */
287
- static VALUE rxml_document_encoding_get(VALUE self)
288
- {
289
- xmlDocPtr xdoc;
290
- const char *xencoding;
291
- Data_Get_Struct(self, xmlDoc, xdoc);
292
-
293
- xencoding = (const char*)xdoc->encoding;
294
- return INT2NUM(xmlParseCharEncoding(xencoding));
295
- }
296
-
297
- /*
298
- * call-seq:
299
- * document.encoding = XML::Encoding::UTF_8
300
- *
301
- * Set the encoding for this document.
302
- */
303
- static VALUE rxml_document_encoding_set(VALUE self, VALUE encoding)
304
- {
305
- xmlDocPtr xdoc;
306
- const char* xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(encoding));
307
-
308
- Data_Get_Struct(self, xmlDoc, xdoc);
309
-
310
- if (xdoc->encoding != NULL)
311
- xmlFree((xmlChar *) xdoc->encoding);
312
-
313
- xdoc->encoding = xmlStrdup((xmlChar *)xencoding);
314
- return self;
315
- }
316
-
317
- /*
318
- * call-seq:
319
- * document.import(node) -> XML::Node
320
- *
321
- * Creates a copy of the node that can be inserted into the
322
- * current document.
323
- */
324
- static VALUE rxml_document_import(VALUE self, VALUE node)
325
- {
326
- xmlDocPtr xdoc;
327
- xmlNodePtr xnode, xresult;
328
-
329
- Data_Get_Struct(self, xmlDoc, xdoc);
330
- Data_Get_Struct(node, xmlNode, xnode);
331
-
332
- xresult = xmlDocCopyNode(xnode, xdoc, 1);
333
-
334
- if (xresult == NULL)
335
- rxml_raise(&xmlLastError);
336
-
337
- return rxml_node_wrap(xresult);
338
- }
339
-
340
- /*
341
- * call-seq:
342
- * document.last -> node
343
- *
344
- * Obtain the last node.
345
- */
346
- static VALUE rxml_document_last_get(VALUE self)
347
- {
348
- xmlDocPtr xdoc;
349
-
350
- Data_Get_Struct(self, xmlDoc, xdoc);
351
-
352
- if (xdoc->last == NULL)
353
- return (Qnil);
354
-
355
- return rxml_node_wrap(xdoc->last);
356
- }
357
-
358
- /*
359
- * call-seq:
360
- * document.last? -> (true|false)
361
- *
362
- * Determine whether there is a last node.
363
- */
364
- static VALUE rxml_document_last_q(VALUE self)
365
- {
366
- xmlDocPtr xdoc;
367
-
368
- Data_Get_Struct(self, xmlDoc, xdoc);
369
-
370
- if (xdoc->last == NULL)
371
- return (Qfalse);
372
- else
373
- return (Qtrue);
374
- }
375
-
376
- /*
377
- * call-seq:
378
- * document.next -> node
379
- *
380
- * Obtain the next node.
381
- */
382
- static VALUE rxml_document_next_get(VALUE self)
383
- {
384
- xmlDocPtr xdoc;
385
-
386
- Data_Get_Struct(self, xmlDoc, xdoc);
387
-
388
- if (xdoc->next == NULL)
389
- return (Qnil);
390
-
391
- return rxml_node_wrap(xdoc->next);
392
- }
393
-
394
- /*
395
- * call-seq:
396
- * document.next? -> (true|false)
397
- *
398
- * Determine whether there is a next node.
399
- */
400
- static VALUE rxml_document_next_q(VALUE self)
401
- {
402
- xmlDocPtr xdoc;
403
-
404
- Data_Get_Struct(self, xmlDoc, xdoc);
405
-
406
- if (xdoc->next == NULL)
407
- return (Qfalse);
408
- else
409
- return (Qtrue);
410
- }
411
-
412
- /*
413
- * call-seq:
414
- * node.type -> num
415
- *
416
- * Obtain this node's type identifier.
417
- */
418
- static VALUE rxml_document_node_type(VALUE self)
419
- {
420
- xmlNodePtr xnode;
421
- Data_Get_Struct(self, xmlNode, xnode);
422
- return (INT2NUM(xnode->type));
423
- }
424
-
425
- /*
426
- * call-seq:
427
- * document.parent -> node
428
- *
429
- * Obtain the parent node.
430
- */
431
- static VALUE rxml_document_parent_get(VALUE self)
432
- {
433
- xmlDocPtr xdoc;
434
-
435
- Data_Get_Struct(self, xmlDoc, xdoc);
436
-
437
- if (xdoc->parent == NULL)
438
- return (Qnil);
439
-
440
- return rxml_node_wrap(xdoc->parent);
441
- }
442
-
443
- /*
444
- * call-seq:
445
- * document.parent? -> (true|false)
446
- *
447
- * Determine whether there is a parent node.
448
- */
449
- static VALUE rxml_document_parent_q(VALUE self)
450
- {
451
- xmlDocPtr xdoc;
452
-
453
- Data_Get_Struct(self, xmlDoc, xdoc);
454
-
455
- if (xdoc->parent == NULL)
456
- return (Qfalse);
457
- else
458
- return (Qtrue);
459
- }
460
-
461
- /*
462
- * call-seq:
463
- * document.prev -> node
464
- *
465
- * Obtain the previous node.
466
- */
467
- static VALUE rxml_document_prev_get(VALUE self)
468
- {
469
- xmlDocPtr xdoc;
470
-
471
- Data_Get_Struct(self, xmlDoc, xdoc);
472
-
473
- if (xdoc->prev == NULL)
474
- return (Qnil);
475
-
476
- return rxml_node_wrap(xdoc->prev);
477
- }
478
-
479
- /*
480
- * call-seq:
481
- * document.prev? -> (true|false)
482
- *
483
- * Determine whether there is a previous node.
484
- */
485
- static VALUE rxml_document_prev_q(VALUE self)
486
- {
487
- xmlDocPtr xdoc;
488
-
489
- Data_Get_Struct(self, xmlDoc, xdoc);
490
-
491
- if (xdoc->prev == NULL)
492
- return (Qfalse);
493
- else
494
- return (Qtrue);
495
- }
496
-
497
- /*
498
- * call-seq:
499
- * document.root -> node
500
- *
501
- * Obtain the root node.
502
- */
503
- static VALUE rxml_document_root_get(VALUE self)
504
- {
505
- xmlDocPtr xdoc;
506
-
507
- xmlNodePtr root;
508
-
509
- Data_Get_Struct(self, xmlDoc, xdoc);
510
- root = xmlDocGetRootElement(xdoc);
511
-
512
- if (root == NULL)
513
- return (Qnil);
514
-
515
- return rxml_node_wrap(root);
516
- }
517
-
518
- /*
519
- * call-seq:
520
- * document.root = node
521
- *
522
- * Set the root node.
523
- */
524
- static VALUE rxml_document_root_set(VALUE self, VALUE node)
525
- {
526
- xmlDocPtr xdoc;
527
- xmlNodePtr xroot, xnode;
528
-
529
- if (rb_obj_is_kind_of(node, cXMLNode) == Qfalse)
530
- rb_raise(rb_eTypeError, "must pass an XML::Node type object");
531
-
532
- Data_Get_Struct(self, xmlDoc, xdoc);
533
- Data_Get_Struct(node, xmlNode, xnode);
534
-
535
- xroot = xmlDocSetRootElement(xdoc, xnode);
536
- return node;
537
- }
538
-
539
- /*
540
- * call-seq:
541
- * document.save(filename) -> int
542
- * document.save(filename, :indent => true, :encoding => 'UTF-8') -> int
543
- *
544
- * Saves a document to a file. You may provide an optional hash table
545
- * to control how the string is generated. Valid options are:
546
- *
547
- * :indent - Specifies if the string should be indented. The default value
548
- * is true. Note that indentation is only added if both :indent is
549
- * true and XML.indent_tree_output is true. If :indent is set to false,
550
- * then both indentation and line feeds are removed from the result.
551
- *
552
- * :encoding - Specifies the output encoding of the string. It
553
- * defaults to the original encoding of the document (see
554
- * #encoding. To override the orginal encoding, use one of the
555
- * XML::Encoding encoding constants. */
556
- static VALUE rxml_document_save(int argc, VALUE *argv, VALUE self)
557
- {
558
- VALUE options = Qnil;
559
- VALUE filename = Qnil;
560
- xmlDocPtr xdoc;
561
- int indent = 1;
562
- const char *xfilename;
563
- const char *xencoding;
564
- int length;
565
-
566
- rb_scan_args(argc, argv, "11", &filename, &options);
567
-
568
- Check_Type(filename, T_STRING);
569
- xfilename = StringValuePtr(filename);
570
-
571
- Data_Get_Struct(self, xmlDoc, xdoc);
572
- xencoding = xdoc->encoding;
573
-
574
- if (!NIL_P(options))
575
- {
576
- VALUE rencoding, rindent;
577
- Check_Type(options, T_HASH);
578
- rencoding = rb_hash_aref(options, ID2SYM(rb_intern("encoding")));
579
- rindent = rb_hash_aref(options, ID2SYM(rb_intern("indent")));
580
-
581
- if (rindent == Qfalse)
582
- indent = 0;
583
-
584
- if (rencoding != Qnil)
585
- {
586
- xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(rencoding));
587
- if (!xencoding)
588
- rb_raise(rb_eArgError, "Unknown encoding value: %d", NUM2INT(rencoding));
589
- }
590
- }
591
-
592
- length = xmlSaveFormatFileEnc(xfilename, xdoc, xencoding, indent);
593
-
594
- if (length == -1)
595
- rxml_raise(&xmlLastError);
596
-
597
- return (INT2NUM(length));
598
- }
599
-
600
- /*
601
- * call-seq:
602
- * document.standalone? -> (true|false)
603
- *
604
- * Determine whether this is a standalone document.
605
- */
606
- static VALUE rxml_document_standalone_q(VALUE self)
607
- {
608
- xmlDocPtr xdoc;
609
-
610
- Data_Get_Struct(self, xmlDoc, xdoc);
611
- if (xdoc->standalone)
612
- return (Qtrue);
613
- else
614
- return (Qfalse);
615
- }
616
-
617
- /*
618
- * call-seq:
619
- * document.to_s -> "string"
620
- * document.to_s(:indent => true, :encoding => 'UTF-8') -> "string"
621
- *
622
- * Converts a document, and all of its children, to a string representation.
623
- * You may provide an optional hash table to control how the string is
624
- * generated. Valid options are:
625
- *
626
- * :indent - Specifies if the string should be indented. The default value
627
- * is true. Note that indentation is only added if both :indent is
628
- * true and XML.indent_tree_output is true. If :indent is set to false,
629
- * then both indentation and line feeds are removed from the result.
630
- *
631
- * :encoding - Specifies the output encoding of the string. It
632
- * defaults to XML::Encoding::UTF8. To change it, use one of the
633
- * XML::Encoding encoding constants. */
634
- static VALUE rxml_document_to_s(int argc, VALUE *argv, VALUE self)
635
- {
636
- VALUE result;
637
- VALUE options = Qnil;
638
- xmlDocPtr xdoc;
639
- int indent = 1;
640
- const char *xencoding = "UTF-8";
641
- xmlChar *buffer;
642
- int length;
643
-
644
- rb_scan_args(argc, argv, "01", &options);
645
-
646
- if (!NIL_P(options))
647
- {
648
- VALUE rencoding, rindent;
649
- Check_Type(options, T_HASH);
650
- rencoding = rb_hash_aref(options, ID2SYM(rb_intern("encoding")));
651
- rindent = rb_hash_aref(options, ID2SYM(rb_intern("indent")));
652
-
653
- if (rindent == Qfalse)
654
- indent = 0;
655
-
656
- if (rencoding != Qnil)
657
- {
658
- xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(rencoding));
659
- if (!xencoding)
660
- rb_raise(rb_eArgError, "Unknown encoding value: %d", NUM2INT(rencoding));
661
- }
662
- }
663
-
664
- Data_Get_Struct(self, xmlDoc, xdoc);
665
- xmlDocDumpFormatMemoryEnc(xdoc, &buffer, &length, xencoding, indent);
666
-
667
- result = rb_str_new((const char*) buffer, length);
668
- xmlFree(buffer);
669
- return result;
670
- }
671
-
672
- /*
673
- * call-seq:
674
- * document.url -> "url"
675
- *
676
- * Obtain this document's source URL, if any.
677
- */
678
- static VALUE rxml_document_url_get(VALUE self)
679
- {
680
- xmlDocPtr xdoc;
681
-
682
- Data_Get_Struct(self, xmlDoc, xdoc);
683
- if (xdoc->URL == NULL)
684
- return (Qnil);
685
- else
686
- return (rb_str_new2((const char*) xdoc->URL));
687
- }
688
-
689
- /*
690
- * call-seq:
691
- * document.version -> "version"
692
- *
693
- * Obtain the XML version specified by this document.
694
- */
695
- static VALUE rxml_document_version_get(VALUE self)
696
- {
697
- xmlDocPtr xdoc;
698
-
699
- Data_Get_Struct(self, xmlDoc, xdoc);
700
- if (xdoc->version == NULL)
701
- return (Qnil);
702
- else
703
- return (rb_str_new2((const char*) xdoc->version));
704
- }
705
-
706
- /*
707
- * call-seq:
708
- * document.xhtml? -> (true|false)
709
- *
710
- * Determine whether this is an XHTML document.
711
- */
712
- static VALUE rxml_document_xhtml_q(VALUE self)
713
- {
714
- xmlDocPtr xdoc;
715
- xmlDtdPtr xdtd;
716
- Data_Get_Struct(self, xmlDoc, xdoc);
717
- xdtd = xmlGetIntSubset(xdoc);
718
- if (xdtd != NULL && xmlIsXHTML(xdtd->SystemID, xdtd->ExternalID) > 0)
719
- return (Qtrue);
720
- else
721
- return (Qfalse);
722
- }
723
-
724
- /*
725
- * call-seq:
726
- * document.xinclude -> num
727
- *
728
- * Process xinclude directives in this document.
729
- */
730
- static VALUE rxml_document_xinclude(VALUE self)
731
- {
732
- #ifdef LIBXML_XINCLUDE_ENABLED
733
- xmlDocPtr xdoc;
734
-
735
- int ret;
736
-
737
- Data_Get_Struct(self, xmlDoc, xdoc);
738
- ret = xmlXIncludeProcess(xdoc);
739
- if (ret >= 0)
740
- {
741
- return(INT2NUM(ret));
742
- }
743
- else
744
- {
745
- rxml_raise(&xmlLastError);
746
- return Qnil;
747
- }
748
- #else
749
- rb_warn(
750
- "libxml was compiled without XInclude support. Please recompile libxml and ruby-libxml");
751
- return (Qfalse);
752
- #endif
753
- }
754
-
755
- void LibXML_validity_error(void * ctxt, const char * msg, va_list ap)
756
- {
757
- if (rb_block_given_p())
758
- {
759
- char buff[1024];
760
- snprintf(buff, 1024, msg, ap);
761
- rb_yield(rb_ary_new3(2, rb_str_new2(buff), Qtrue));
762
- }
763
- else
764
- {
765
- fprintf(stderr, "error -- found validity error: ");
766
- fprintf(stderr, msg, ap);
767
- }
768
- }
769
-
770
- /*
771
- * call-seq:
772
- * document.order_elements!
773
- *
774
- * Call this routine to speed up XPath computation on static documents.
775
- * This stamps all the element nodes with the document order.
776
- */
777
- static VALUE rxml_document_order_elements(VALUE self)
778
- {
779
- xmlDocPtr xdoc;
780
-
781
- Data_Get_Struct(self, xmlDoc, xdoc);
782
- return LONG2FIX(xmlXPathOrderDocElems(xdoc));
783
- }
784
-
785
- /*
786
- * call-seq:
787
- * document.validate_schema(schema) -> (true|false)
788
- *
789
- * Validate this document against the specified XML::Schema.
790
- *
791
- * If a block is provided it is used as an error handler for validaten errors.
792
- * The block is called with two argument, the message and a flag indication
793
- * if the message is an error (true) or a warning (false).
794
- */
795
- static VALUE rxml_document_validate_schema(VALUE self, VALUE schema)
796
- {
797
- xmlSchemaValidCtxtPtr vptr;
798
- xmlDocPtr xdoc;
799
- xmlSchemaPtr xschema;
800
- int is_invalid;
801
-
802
- Data_Get_Struct(self, xmlDoc, xdoc);
803
- Data_Get_Struct(schema, xmlSchema, xschema);
804
-
805
- vptr = xmlSchemaNewValidCtxt(xschema);
806
-
807
- xmlSchemaSetValidErrors(vptr,
808
- (xmlSchemaValidityErrorFunc) LibXML_validity_error,
809
- (xmlSchemaValidityWarningFunc) LibXML_validity_warning, NULL);
810
-
811
- is_invalid = xmlSchemaValidateDoc(vptr, xdoc);
812
- xmlSchemaFreeValidCtxt(vptr);
813
- if (is_invalid)
814
- {
815
- rxml_raise(&xmlLastError);
816
- return Qfalse;
817
- }
818
- else
819
- {
820
- return Qtrue;
821
- }
822
- }
823
-
824
- /*
825
- * call-seq:
826
- * document.validate_schema(relaxng) -> (true|false)
827
- *
828
- * Validate this document against the specified XML::RelaxNG.
829
- *
830
- * If a block is provided it is used as an error handler for validaten errors.
831
- * The block is called with two argument, the message and a flag indication
832
- * if the message is an error (true) or a warning (false).
833
- */
834
- static VALUE rxml_document_validate_relaxng(VALUE self, VALUE relaxng)
835
- {
836
- xmlRelaxNGValidCtxtPtr vptr;
837
- xmlDocPtr xdoc;
838
- xmlRelaxNGPtr xrelaxng;
839
- int is_invalid;
840
-
841
- Data_Get_Struct(self, xmlDoc, xdoc);
842
- Data_Get_Struct(relaxng, xmlRelaxNG, xrelaxng);
843
-
844
- vptr = xmlRelaxNGNewValidCtxt(xrelaxng);
845
-
846
- xmlRelaxNGSetValidErrors(vptr,
847
- (xmlRelaxNGValidityErrorFunc) LibXML_validity_error,
848
- (xmlRelaxNGValidityWarningFunc) LibXML_validity_warning, NULL);
849
-
850
- is_invalid = xmlRelaxNGValidateDoc(vptr, xdoc);
851
- xmlRelaxNGFreeValidCtxt(vptr);
852
- if (is_invalid)
853
- {
854
- rxml_raise(&xmlLastError);
855
- return Qfalse;
856
- }
857
- else
858
- {
859
- return Qtrue;
860
- }
861
- }
862
-
863
- /*
864
- * call-seq:
865
- * document.validate(dtd) -> (true|false)
866
- *
867
- * Validate this document against the specified XML::DTD.
868
- */
869
- static VALUE rxml_document_validate_dtd(VALUE self, VALUE dtd)
870
- {
871
- VALUE error = Qnil;
872
- xmlValidCtxt ctxt;
873
- xmlDocPtr xdoc;
874
- xmlDtdPtr xdtd;
875
-
876
- Data_Get_Struct(self, xmlDoc, xdoc);
877
- Data_Get_Struct(dtd, xmlDtd, xdtd);
878
-
879
- ctxt.userData = &error;
880
- ctxt.error = (xmlValidityErrorFunc) LibXML_validity_error;
881
- ctxt.warning = (xmlValidityWarningFunc) LibXML_validity_warning;
882
-
883
- ctxt.nodeNr = 0;
884
- ctxt.nodeTab = NULL;
885
- ctxt.vstateNr = 0;
886
- ctxt.vstateTab = NULL;
887
-
888
- if (xmlValidateDtd(&ctxt, xdoc, xdtd))
889
- {
890
- return (Qtrue);
891
- }
892
- else
893
- {
894
- rxml_raise(&xmlLastError);
895
- return Qfalse;
896
- }
897
- }
898
-
899
- void rxml_init_document(void)
900
- {
901
- cXMLDocument = rb_define_class_under(mXML, "Document", rb_cObject);
902
- rb_define_alloc_func(cXMLDocument, rxml_document_alloc);
903
-
904
- rb_define_method(cXMLDocument, "initialize", rxml_document_initialize, -1);
905
- rb_define_method(cXMLDocument, "child", rxml_document_child_get, 0);
906
- rb_define_method(cXMLDocument, "child?", rxml_document_child_q, 0);
907
- rb_define_method(cXMLDocument, "compression", rxml_document_compression_get, 0);
908
- rb_define_method(cXMLDocument, "compression=", rxml_document_compression_set, 1);
909
- rb_define_method(cXMLDocument, "compression?", rxml_document_compression_q, 0);
910
- rb_define_method(cXMLDocument, "debug", rxml_document_debug, 0);
911
- rb_define_method(cXMLDocument, "encoding", rxml_document_encoding_get, 0);
912
- rb_define_method(cXMLDocument, "encoding=", rxml_document_encoding_set, 1);
913
- rb_define_method(cXMLDocument, "import", rxml_document_import, 1);
914
- rb_define_method(cXMLDocument, "last", rxml_document_last_get, 0);
915
- rb_define_method(cXMLDocument, "last?", rxml_document_last_q, 0);
916
- rb_define_method(cXMLDocument, "next", rxml_document_next_get, 0);
917
- rb_define_method(cXMLDocument, "next?", rxml_document_next_q, 0);
918
- rb_define_method(cXMLDocument, "node_type", rxml_document_node_type, 0);
919
- rb_define_method(cXMLDocument, "order_elements!", rxml_document_order_elements, 0);
920
- rb_define_method(cXMLDocument, "parent", rxml_document_parent_get, 0);
921
- rb_define_method(cXMLDocument, "parent?", rxml_document_parent_q, 0);
922
- rb_define_method(cXMLDocument, "prev", rxml_document_prev_get, 0);
923
- rb_define_method(cXMLDocument, "prev?", rxml_document_prev_q, 0);
924
- rb_define_method(cXMLDocument, "root", rxml_document_root_get, 0);
925
- rb_define_method(cXMLDocument, "root=", rxml_document_root_set, 1);
926
- rb_define_method(cXMLDocument, "save", rxml_document_save, -1);
927
- rb_define_method(cXMLDocument, "standalone?", rxml_document_standalone_q, 0);
928
- rb_define_method(cXMLDocument, "to_s", rxml_document_to_s, -1);
929
- rb_define_method(cXMLDocument, "url", rxml_document_url_get, 0);
930
- rb_define_method(cXMLDocument, "version", rxml_document_version_get, 0);
931
- rb_define_method(cXMLDocument, "xhtml?", rxml_document_xhtml_q, 0);
932
- rb_define_method(cXMLDocument, "xinclude", rxml_document_xinclude, 0);
933
- rb_define_method(cXMLDocument, "validate", rxml_document_validate_dtd, 1);
934
- rb_define_method(cXMLDocument, "validate_schema", rxml_document_validate_schema, 1);
935
- rb_define_method(cXMLDocument, "validate_relaxng", rxml_document_validate_relaxng, 1);
936
- }
1
+ /* $Id$ */
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.compression -> num
146
+ *
147
+ * Obtain this document's compression mode identifier.
148
+ */
149
+ static VALUE rxml_document_compression_get(VALUE self)
150
+ {
151
+ #ifdef HAVE_ZLIB_H
152
+ xmlDocPtr xdoc;
153
+
154
+ int compmode;
155
+ Data_Get_Struct(self, xmlDoc, xdoc);
156
+
157
+ compmode = xmlGetDocCompressMode(xdoc);
158
+ if (compmode == -1)
159
+ return(Qnil);
160
+ else
161
+ return(INT2NUM(compmode));
162
+ #else
163
+ rb_warn("libxml not compiled with zlib support");
164
+ return (Qfalse);
165
+ #endif
166
+ }
167
+
168
+ /*
169
+ * call-seq:
170
+ * document.compression = num
171
+ *
172
+ * Set this document's compression mode.
173
+ */
174
+ static VALUE rxml_document_compression_set(VALUE self, VALUE num)
175
+ {
176
+ #ifdef HAVE_ZLIB_H
177
+ xmlDocPtr xdoc;
178
+
179
+ int compmode;
180
+ Check_Type(num, T_FIXNUM);
181
+ Data_Get_Struct(self, xmlDoc, xdoc);
182
+
183
+ if (xdoc == NULL)
184
+ {
185
+ return(Qnil);
186
+ }
187
+ else
188
+ {
189
+ xmlSetDocCompressMode(xdoc, NUM2INT(num));
190
+
191
+ compmode = xmlGetDocCompressMode(xdoc);
192
+ if (compmode == -1)
193
+ return(Qnil);
194
+ else
195
+ return(INT2NUM(compmode));
196
+ }
197
+ #else
198
+ rb_warn("libxml compiled without zlib support");
199
+ return (Qfalse);
200
+ #endif
201
+ }
202
+
203
+ /*
204
+ * call-seq:
205
+ * document.compression? -> (true|false)
206
+ *
207
+ * Determine whether this document is compressed.
208
+ */
209
+ static VALUE rxml_document_compression_q(VALUE self)
210
+ {
211
+ #ifdef HAVE_ZLIB_H
212
+ xmlDocPtr xdoc;
213
+
214
+ Data_Get_Struct(self, xmlDoc, xdoc);
215
+
216
+ if (xdoc->compression != -1)
217
+ return(Qtrue);
218
+ else
219
+ return(Qfalse);
220
+ #else
221
+ rb_warn("libxml compiled without zlib support");
222
+ return (Qfalse);
223
+ #endif
224
+ }
225
+
226
+ /*
227
+ * call-seq:
228
+ * document.child -> node
229
+ *
230
+ * Get this document's child node.
231
+ */
232
+ static VALUE rxml_document_child_get(VALUE self)
233
+ {
234
+ xmlDocPtr xdoc;
235
+ Data_Get_Struct(self, xmlDoc, xdoc);
236
+
237
+ if (xdoc->children == NULL)
238
+ return (Qnil);
239
+
240
+ return rxml_node_wrap(xdoc->children);
241
+ }
242
+
243
+ /*
244
+ * call-seq:
245
+ * document.child? -> (true|false)
246
+ *
247
+ * Determine whether this document has a child node.
248
+ */
249
+ static VALUE rxml_document_child_q(VALUE self)
250
+ {
251
+ xmlDocPtr xdoc;
252
+ Data_Get_Struct(self, xmlDoc, xdoc);
253
+
254
+ if (xdoc->children == NULL)
255
+ return (Qfalse);
256
+ else
257
+ return (Qtrue);
258
+ }
259
+
260
+
261
+ /*
262
+ * call-seq:
263
+ * node.debug -> true|false
264
+ *
265
+ * Print libxml debugging information to stdout.
266
+ * Requires that libxml was compiled with debugging enabled.
267
+ */
268
+ static VALUE rxml_document_debug(VALUE self)
269
+ {
270
+ #ifdef LIBXML_DEBUG_ENABLED
271
+ xmlDocPtr xdoc;
272
+ Data_Get_Struct(self, xmlDoc, xdoc);
273
+ xmlDebugDumpDocument(NULL, xdoc);
274
+ return Qtrue;
275
+ #else
276
+ rb_warn("libxml was compiled without debugging support.")
277
+ return Qfalse;
278
+ #endif
279
+ }
280
+
281
+ /*
282
+ * call-seq:
283
+ * document.encoding -> XML::Encoding::UTF_8
284
+ *
285
+ * Obtain the encoding specified by this document.
286
+ */
287
+ static VALUE rxml_document_encoding_get(VALUE self)
288
+ {
289
+ xmlDocPtr xdoc;
290
+ const char *xencoding;
291
+ Data_Get_Struct(self, xmlDoc, xdoc);
292
+
293
+ xencoding = (const char*)xdoc->encoding;
294
+ return INT2NUM(xmlParseCharEncoding(xencoding));
295
+ }
296
+
297
+ /*
298
+ * call-seq:
299
+ * document.encoding = XML::Encoding::UTF_8
300
+ *
301
+ * Set the encoding for this document.
302
+ */
303
+ static VALUE rxml_document_encoding_set(VALUE self, VALUE encoding)
304
+ {
305
+ xmlDocPtr xdoc;
306
+ const char* xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(encoding));
307
+
308
+ Data_Get_Struct(self, xmlDoc, xdoc);
309
+
310
+ if (xdoc->encoding != NULL)
311
+ xmlFree((xmlChar *) xdoc->encoding);
312
+
313
+ xdoc->encoding = xmlStrdup((xmlChar *)xencoding);
314
+ return self;
315
+ }
316
+
317
+ /*
318
+ * call-seq:
319
+ * document.import(node) -> XML::Node
320
+ *
321
+ * Creates a copy of the node that can be inserted into the
322
+ * current document.
323
+ */
324
+ static VALUE rxml_document_import(VALUE self, VALUE node)
325
+ {
326
+ xmlDocPtr xdoc;
327
+ xmlNodePtr xnode, xresult;
328
+
329
+ Data_Get_Struct(self, xmlDoc, xdoc);
330
+ Data_Get_Struct(node, xmlNode, xnode);
331
+
332
+ xresult = xmlDocCopyNode(xnode, xdoc, 1);
333
+
334
+ if (xresult == NULL)
335
+ rxml_raise(&xmlLastError);
336
+
337
+ return rxml_node_wrap(xresult);
338
+ }
339
+
340
+ /*
341
+ * call-seq:
342
+ * document.last -> node
343
+ *
344
+ * Obtain the last node.
345
+ */
346
+ static VALUE rxml_document_last_get(VALUE self)
347
+ {
348
+ xmlDocPtr xdoc;
349
+
350
+ Data_Get_Struct(self, xmlDoc, xdoc);
351
+
352
+ if (xdoc->last == NULL)
353
+ return (Qnil);
354
+
355
+ return rxml_node_wrap(xdoc->last);
356
+ }
357
+
358
+ /*
359
+ * call-seq:
360
+ * document.last? -> (true|false)
361
+ *
362
+ * Determine whether there is a last node.
363
+ */
364
+ static VALUE rxml_document_last_q(VALUE self)
365
+ {
366
+ xmlDocPtr xdoc;
367
+
368
+ Data_Get_Struct(self, xmlDoc, xdoc);
369
+
370
+ if (xdoc->last == NULL)
371
+ return (Qfalse);
372
+ else
373
+ return (Qtrue);
374
+ }
375
+
376
+ /*
377
+ * call-seq:
378
+ * document.next -> node
379
+ *
380
+ * Obtain the next node.
381
+ */
382
+ static VALUE rxml_document_next_get(VALUE self)
383
+ {
384
+ xmlDocPtr xdoc;
385
+
386
+ Data_Get_Struct(self, xmlDoc, xdoc);
387
+
388
+ if (xdoc->next == NULL)
389
+ return (Qnil);
390
+
391
+ return rxml_node_wrap(xdoc->next);
392
+ }
393
+
394
+ /*
395
+ * call-seq:
396
+ * document.next? -> (true|false)
397
+ *
398
+ * Determine whether there is a next node.
399
+ */
400
+ static VALUE rxml_document_next_q(VALUE self)
401
+ {
402
+ xmlDocPtr xdoc;
403
+
404
+ Data_Get_Struct(self, xmlDoc, xdoc);
405
+
406
+ if (xdoc->next == NULL)
407
+ return (Qfalse);
408
+ else
409
+ return (Qtrue);
410
+ }
411
+
412
+ /*
413
+ * call-seq:
414
+ * node.type -> num
415
+ *
416
+ * Obtain this node's type identifier.
417
+ */
418
+ static VALUE rxml_document_node_type(VALUE self)
419
+ {
420
+ xmlNodePtr xnode;
421
+ Data_Get_Struct(self, xmlNode, xnode);
422
+ return (INT2NUM(xnode->type));
423
+ }
424
+
425
+ /*
426
+ * call-seq:
427
+ * document.parent -> node
428
+ *
429
+ * Obtain the parent node.
430
+ */
431
+ static VALUE rxml_document_parent_get(VALUE self)
432
+ {
433
+ xmlDocPtr xdoc;
434
+
435
+ Data_Get_Struct(self, xmlDoc, xdoc);
436
+
437
+ if (xdoc->parent == NULL)
438
+ return (Qnil);
439
+
440
+ return rxml_node_wrap(xdoc->parent);
441
+ }
442
+
443
+ /*
444
+ * call-seq:
445
+ * document.parent? -> (true|false)
446
+ *
447
+ * Determine whether there is a parent node.
448
+ */
449
+ static VALUE rxml_document_parent_q(VALUE self)
450
+ {
451
+ xmlDocPtr xdoc;
452
+
453
+ Data_Get_Struct(self, xmlDoc, xdoc);
454
+
455
+ if (xdoc->parent == NULL)
456
+ return (Qfalse);
457
+ else
458
+ return (Qtrue);
459
+ }
460
+
461
+ /*
462
+ * call-seq:
463
+ * document.prev -> node
464
+ *
465
+ * Obtain the previous node.
466
+ */
467
+ static VALUE rxml_document_prev_get(VALUE self)
468
+ {
469
+ xmlDocPtr xdoc;
470
+
471
+ Data_Get_Struct(self, xmlDoc, xdoc);
472
+
473
+ if (xdoc->prev == NULL)
474
+ return (Qnil);
475
+
476
+ return rxml_node_wrap(xdoc->prev);
477
+ }
478
+
479
+ /*
480
+ * call-seq:
481
+ * document.prev? -> (true|false)
482
+ *
483
+ * Determine whether there is a previous node.
484
+ */
485
+ static VALUE rxml_document_prev_q(VALUE self)
486
+ {
487
+ xmlDocPtr xdoc;
488
+
489
+ Data_Get_Struct(self, xmlDoc, xdoc);
490
+
491
+ if (xdoc->prev == NULL)
492
+ return (Qfalse);
493
+ else
494
+ return (Qtrue);
495
+ }
496
+
497
+ /*
498
+ * call-seq:
499
+ * document.root -> node
500
+ *
501
+ * Obtain the root node.
502
+ */
503
+ static VALUE rxml_document_root_get(VALUE self)
504
+ {
505
+ xmlDocPtr xdoc;
506
+
507
+ xmlNodePtr root;
508
+
509
+ Data_Get_Struct(self, xmlDoc, xdoc);
510
+ root = xmlDocGetRootElement(xdoc);
511
+
512
+ if (root == NULL)
513
+ return (Qnil);
514
+
515
+ return rxml_node_wrap(root);
516
+ }
517
+
518
+ /*
519
+ * call-seq:
520
+ * document.root = node
521
+ *
522
+ * Set the root node.
523
+ */
524
+ static VALUE rxml_document_root_set(VALUE self, VALUE node)
525
+ {
526
+ xmlDocPtr xdoc;
527
+ xmlNodePtr xroot, xnode;
528
+
529
+ if (rb_obj_is_kind_of(node, cXMLNode) == Qfalse)
530
+ rb_raise(rb_eTypeError, "must pass an XML::Node type object");
531
+
532
+ Data_Get_Struct(self, xmlDoc, xdoc);
533
+ Data_Get_Struct(node, xmlNode, xnode);
534
+
535
+ xroot = xmlDocSetRootElement(xdoc, xnode);
536
+ return node;
537
+ }
538
+
539
+ /*
540
+ * call-seq:
541
+ * document.save(filename) -> int
542
+ * document.save(filename, :indent => true, :encoding => 'UTF-8') -> int
543
+ *
544
+ * Saves a document to a file. You may provide an optional hash table
545
+ * to control how the string is generated. Valid options are:
546
+ *
547
+ * :indent - Specifies if the string should be indented. The default value
548
+ * is true. Note that indentation is only added if both :indent is
549
+ * true and XML.indent_tree_output is true. If :indent is set to false,
550
+ * then both indentation and line feeds are removed from the result.
551
+ *
552
+ * :encoding - Specifies the output encoding of the string. It
553
+ * defaults to the original encoding of the document (see
554
+ * #encoding. To override the orginal encoding, use one of the
555
+ * XML::Encoding encoding constants. */
556
+ static VALUE rxml_document_save(int argc, VALUE *argv, VALUE self)
557
+ {
558
+ VALUE options = Qnil;
559
+ VALUE filename = Qnil;
560
+ xmlDocPtr xdoc;
561
+ int indent = 1;
562
+ const char *xfilename;
563
+ const char *xencoding;
564
+ int length;
565
+
566
+ rb_scan_args(argc, argv, "11", &filename, &options);
567
+
568
+ Check_Type(filename, T_STRING);
569
+ xfilename = StringValuePtr(filename);
570
+
571
+ Data_Get_Struct(self, xmlDoc, xdoc);
572
+ xencoding = xdoc->encoding;
573
+
574
+ if (!NIL_P(options))
575
+ {
576
+ VALUE rencoding, rindent;
577
+ Check_Type(options, T_HASH);
578
+ rencoding = rb_hash_aref(options, ID2SYM(rb_intern("encoding")));
579
+ rindent = rb_hash_aref(options, ID2SYM(rb_intern("indent")));
580
+
581
+ if (rindent == Qfalse)
582
+ indent = 0;
583
+
584
+ if (rencoding != Qnil)
585
+ {
586
+ xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(rencoding));
587
+ if (!xencoding)
588
+ rb_raise(rb_eArgError, "Unknown encoding value: %d", NUM2INT(rencoding));
589
+ }
590
+ }
591
+
592
+ length = xmlSaveFormatFileEnc(xfilename, xdoc, xencoding, indent);
593
+
594
+ if (length == -1)
595
+ rxml_raise(&xmlLastError);
596
+
597
+ return (INT2NUM(length));
598
+ }
599
+
600
+ /*
601
+ * call-seq:
602
+ * document.standalone? -> (true|false)
603
+ *
604
+ * Determine whether this is a standalone document.
605
+ */
606
+ static VALUE rxml_document_standalone_q(VALUE self)
607
+ {
608
+ xmlDocPtr xdoc;
609
+
610
+ Data_Get_Struct(self, xmlDoc, xdoc);
611
+ if (xdoc->standalone)
612
+ return (Qtrue);
613
+ else
614
+ return (Qfalse);
615
+ }
616
+
617
+ /*
618
+ * call-seq:
619
+ * document.to_s -> "string"
620
+ * document.to_s(:indent => true, :encoding => 'UTF-8') -> "string"
621
+ *
622
+ * Converts a document, and all of its children, to a string representation.
623
+ * You may provide an optional hash table to control how the string is
624
+ * generated. Valid options are:
625
+ *
626
+ * :indent - Specifies if the string should be indented. The default value
627
+ * is true. Note that indentation is only added if both :indent is
628
+ * true and XML.indent_tree_output is true. If :indent is set to false,
629
+ * then both indentation and line feeds are removed from the result.
630
+ *
631
+ * :encoding - Specifies the output encoding of the string. It
632
+ * defaults to XML::Encoding::UTF8. To change it, use one of the
633
+ * XML::Encoding encoding constants. */
634
+ static VALUE rxml_document_to_s(int argc, VALUE *argv, VALUE self)
635
+ {
636
+ VALUE result;
637
+ VALUE options = Qnil;
638
+ xmlDocPtr xdoc;
639
+ int indent = 1;
640
+ const char *xencoding = "UTF-8";
641
+ xmlChar *buffer;
642
+ int length;
643
+
644
+ rb_scan_args(argc, argv, "01", &options);
645
+
646
+ if (!NIL_P(options))
647
+ {
648
+ VALUE rencoding, rindent;
649
+ Check_Type(options, T_HASH);
650
+ rencoding = rb_hash_aref(options, ID2SYM(rb_intern("encoding")));
651
+ rindent = rb_hash_aref(options, ID2SYM(rb_intern("indent")));
652
+
653
+ if (rindent == Qfalse)
654
+ indent = 0;
655
+
656
+ if (rencoding != Qnil)
657
+ {
658
+ xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(rencoding));
659
+ if (!xencoding)
660
+ rb_raise(rb_eArgError, "Unknown encoding value: %d", NUM2INT(rencoding));
661
+ }
662
+ }
663
+
664
+ Data_Get_Struct(self, xmlDoc, xdoc);
665
+ xmlDocDumpFormatMemoryEnc(xdoc, &buffer, &length, xencoding, indent);
666
+
667
+ result = rb_str_new((const char*) buffer, length);
668
+ xmlFree(buffer);
669
+ return result;
670
+ }
671
+
672
+ /*
673
+ * call-seq:
674
+ * document.url -> "url"
675
+ *
676
+ * Obtain this document's source URL, if any.
677
+ */
678
+ static VALUE rxml_document_url_get(VALUE self)
679
+ {
680
+ xmlDocPtr xdoc;
681
+
682
+ Data_Get_Struct(self, xmlDoc, xdoc);
683
+ if (xdoc->URL == NULL)
684
+ return (Qnil);
685
+ else
686
+ return (rb_str_new2((const char*) xdoc->URL));
687
+ }
688
+
689
+ /*
690
+ * call-seq:
691
+ * document.version -> "version"
692
+ *
693
+ * Obtain the XML version specified by this document.
694
+ */
695
+ static VALUE rxml_document_version_get(VALUE self)
696
+ {
697
+ xmlDocPtr xdoc;
698
+
699
+ Data_Get_Struct(self, xmlDoc, xdoc);
700
+ if (xdoc->version == NULL)
701
+ return (Qnil);
702
+ else
703
+ return (rb_str_new2((const char*) xdoc->version));
704
+ }
705
+
706
+ /*
707
+ * call-seq:
708
+ * document.xhtml? -> (true|false)
709
+ *
710
+ * Determine whether this is an XHTML document.
711
+ */
712
+ static VALUE rxml_document_xhtml_q(VALUE self)
713
+ {
714
+ xmlDocPtr xdoc;
715
+ xmlDtdPtr xdtd;
716
+ Data_Get_Struct(self, xmlDoc, xdoc);
717
+ xdtd = xmlGetIntSubset(xdoc);
718
+ if (xdtd != NULL && xmlIsXHTML(xdtd->SystemID, xdtd->ExternalID) > 0)
719
+ return (Qtrue);
720
+ else
721
+ return (Qfalse);
722
+ }
723
+
724
+ /*
725
+ * call-seq:
726
+ * document.xinclude -> num
727
+ *
728
+ * Process xinclude directives in this document.
729
+ */
730
+ static VALUE rxml_document_xinclude(VALUE self)
731
+ {
732
+ #ifdef LIBXML_XINCLUDE_ENABLED
733
+ xmlDocPtr xdoc;
734
+
735
+ int ret;
736
+
737
+ Data_Get_Struct(self, xmlDoc, xdoc);
738
+ ret = xmlXIncludeProcess(xdoc);
739
+ if (ret >= 0)
740
+ {
741
+ return(INT2NUM(ret));
742
+ }
743
+ else
744
+ {
745
+ rxml_raise(&xmlLastError);
746
+ return Qnil;
747
+ }
748
+ #else
749
+ rb_warn(
750
+ "libxml was compiled without XInclude support. Please recompile libxml and ruby-libxml");
751
+ return (Qfalse);
752
+ #endif
753
+ }
754
+
755
+ void LibXML_validity_error(void * ctxt, const char * msg, va_list ap)
756
+ {
757
+ if (rb_block_given_p())
758
+ {
759
+ char buff[1024];
760
+ snprintf(buff, 1024, msg, ap);
761
+ rb_yield(rb_ary_new3(2, rb_str_new2(buff), Qtrue));
762
+ }
763
+ else
764
+ {
765
+ fprintf(stderr, "error -- found validity error: ");
766
+ fprintf(stderr, msg, ap);
767
+ }
768
+ }
769
+
770
+ /*
771
+ * call-seq:
772
+ * document.order_elements!
773
+ *
774
+ * Call this routine to speed up XPath computation on static documents.
775
+ * This stamps all the element nodes with the document order.
776
+ */
777
+ static VALUE rxml_document_order_elements(VALUE self)
778
+ {
779
+ xmlDocPtr xdoc;
780
+
781
+ Data_Get_Struct(self, xmlDoc, xdoc);
782
+ return LONG2FIX(xmlXPathOrderDocElems(xdoc));
783
+ }
784
+
785
+ /*
786
+ * call-seq:
787
+ * document.validate_schema(schema) -> (true|false)
788
+ *
789
+ * Validate this document against the specified XML::Schema.
790
+ *
791
+ * If a block is provided it is used as an error handler for validaten errors.
792
+ * The block is called with two argument, the message and a flag indication
793
+ * if the message is an error (true) or a warning (false).
794
+ */
795
+ static VALUE rxml_document_validate_schema(VALUE self, VALUE schema)
796
+ {
797
+ xmlSchemaValidCtxtPtr vptr;
798
+ xmlDocPtr xdoc;
799
+ xmlSchemaPtr xschema;
800
+ int is_invalid;
801
+
802
+ Data_Get_Struct(self, xmlDoc, xdoc);
803
+ Data_Get_Struct(schema, xmlSchema, xschema);
804
+
805
+ vptr = xmlSchemaNewValidCtxt(xschema);
806
+
807
+ xmlSchemaSetValidErrors(vptr,
808
+ (xmlSchemaValidityErrorFunc) LibXML_validity_error,
809
+ (xmlSchemaValidityWarningFunc) LibXML_validity_warning, NULL);
810
+
811
+ is_invalid = xmlSchemaValidateDoc(vptr, xdoc);
812
+ xmlSchemaFreeValidCtxt(vptr);
813
+ if (is_invalid)
814
+ {
815
+ rxml_raise(&xmlLastError);
816
+ return Qfalse;
817
+ }
818
+ else
819
+ {
820
+ return Qtrue;
821
+ }
822
+ }
823
+
824
+ /*
825
+ * call-seq:
826
+ * document.validate_schema(relaxng) -> (true|false)
827
+ *
828
+ * Validate this document against the specified XML::RelaxNG.
829
+ *
830
+ * If a block is provided it is used as an error handler for validaten errors.
831
+ * The block is called with two argument, the message and a flag indication
832
+ * if the message is an error (true) or a warning (false).
833
+ */
834
+ static VALUE rxml_document_validate_relaxng(VALUE self, VALUE relaxng)
835
+ {
836
+ xmlRelaxNGValidCtxtPtr vptr;
837
+ xmlDocPtr xdoc;
838
+ xmlRelaxNGPtr xrelaxng;
839
+ int is_invalid;
840
+
841
+ Data_Get_Struct(self, xmlDoc, xdoc);
842
+ Data_Get_Struct(relaxng, xmlRelaxNG, xrelaxng);
843
+
844
+ vptr = xmlRelaxNGNewValidCtxt(xrelaxng);
845
+
846
+ xmlRelaxNGSetValidErrors(vptr,
847
+ (xmlRelaxNGValidityErrorFunc) LibXML_validity_error,
848
+ (xmlRelaxNGValidityWarningFunc) LibXML_validity_warning, NULL);
849
+
850
+ is_invalid = xmlRelaxNGValidateDoc(vptr, xdoc);
851
+ xmlRelaxNGFreeValidCtxt(vptr);
852
+ if (is_invalid)
853
+ {
854
+ rxml_raise(&xmlLastError);
855
+ return Qfalse;
856
+ }
857
+ else
858
+ {
859
+ return Qtrue;
860
+ }
861
+ }
862
+
863
+ /*
864
+ * call-seq:
865
+ * document.validate(dtd) -> (true|false)
866
+ *
867
+ * Validate this document against the specified XML::DTD.
868
+ */
869
+ static VALUE rxml_document_validate_dtd(VALUE self, VALUE dtd)
870
+ {
871
+ VALUE error = Qnil;
872
+ xmlValidCtxt ctxt;
873
+ xmlDocPtr xdoc;
874
+ xmlDtdPtr xdtd;
875
+
876
+ Data_Get_Struct(self, xmlDoc, xdoc);
877
+ Data_Get_Struct(dtd, xmlDtd, xdtd);
878
+
879
+ ctxt.userData = &error;
880
+ ctxt.error = (xmlValidityErrorFunc) LibXML_validity_error;
881
+ ctxt.warning = (xmlValidityWarningFunc) LibXML_validity_warning;
882
+
883
+ ctxt.nodeNr = 0;
884
+ ctxt.nodeTab = NULL;
885
+ ctxt.vstateNr = 0;
886
+ ctxt.vstateTab = NULL;
887
+
888
+ if (xmlValidateDtd(&ctxt, xdoc, xdtd))
889
+ {
890
+ return (Qtrue);
891
+ }
892
+ else
893
+ {
894
+ rxml_raise(&xmlLastError);
895
+ return Qfalse;
896
+ }
897
+ }
898
+
899
+ void rxml_init_document(void)
900
+ {
901
+ cXMLDocument = rb_define_class_under(mXML, "Document", rb_cObject);
902
+ rb_define_alloc_func(cXMLDocument, rxml_document_alloc);
903
+
904
+ rb_define_method(cXMLDocument, "initialize", rxml_document_initialize, -1);
905
+ rb_define_method(cXMLDocument, "child", rxml_document_child_get, 0);
906
+ rb_define_method(cXMLDocument, "child?", rxml_document_child_q, 0);
907
+ rb_define_method(cXMLDocument, "compression", rxml_document_compression_get, 0);
908
+ rb_define_method(cXMLDocument, "compression=", rxml_document_compression_set, 1);
909
+ rb_define_method(cXMLDocument, "compression?", rxml_document_compression_q, 0);
910
+ rb_define_method(cXMLDocument, "debug", rxml_document_debug, 0);
911
+ rb_define_method(cXMLDocument, "encoding", rxml_document_encoding_get, 0);
912
+ rb_define_method(cXMLDocument, "encoding=", rxml_document_encoding_set, 1);
913
+ rb_define_method(cXMLDocument, "import", rxml_document_import, 1);
914
+ rb_define_method(cXMLDocument, "last", rxml_document_last_get, 0);
915
+ rb_define_method(cXMLDocument, "last?", rxml_document_last_q, 0);
916
+ rb_define_method(cXMLDocument, "next", rxml_document_next_get, 0);
917
+ rb_define_method(cXMLDocument, "next?", rxml_document_next_q, 0);
918
+ rb_define_method(cXMLDocument, "node_type", rxml_document_node_type, 0);
919
+ rb_define_method(cXMLDocument, "order_elements!", rxml_document_order_elements, 0);
920
+ rb_define_method(cXMLDocument, "parent", rxml_document_parent_get, 0);
921
+ rb_define_method(cXMLDocument, "parent?", rxml_document_parent_q, 0);
922
+ rb_define_method(cXMLDocument, "prev", rxml_document_prev_get, 0);
923
+ rb_define_method(cXMLDocument, "prev?", rxml_document_prev_q, 0);
924
+ rb_define_method(cXMLDocument, "root", rxml_document_root_get, 0);
925
+ rb_define_method(cXMLDocument, "root=", rxml_document_root_set, 1);
926
+ rb_define_method(cXMLDocument, "save", rxml_document_save, -1);
927
+ rb_define_method(cXMLDocument, "standalone?", rxml_document_standalone_q, 0);
928
+ rb_define_method(cXMLDocument, "to_s", rxml_document_to_s, -1);
929
+ rb_define_method(cXMLDocument, "url", rxml_document_url_get, 0);
930
+ rb_define_method(cXMLDocument, "version", rxml_document_version_get, 0);
931
+ rb_define_method(cXMLDocument, "xhtml?", rxml_document_xhtml_q, 0);
932
+ rb_define_method(cXMLDocument, "xinclude", rxml_document_xinclude, 0);
933
+ rb_define_method(cXMLDocument, "validate", rxml_document_validate_dtd, 1);
934
+ rb_define_method(cXMLDocument, "validate_schema", rxml_document_validate_schema, 1);
935
+ rb_define_method(cXMLDocument, "validate_relaxng", rxml_document_validate_relaxng, 1);
936
+ }