libxml-ruby 0.9.3-x86-mswin32-60 → 0.9.4-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.
- data/CHANGES +9 -0
- data/README +61 -128
- data/doc/css/normal.css +182 -0
- data/doc/img/raze-tiny.png +0 -0
- data/doc/img/red-cube.jpg +0 -0
- data/doc/img/xml-ruby.png +0 -0
- data/doc/index.xml +43 -0
- data/doc/install.xml +77 -0
- data/doc/layout.rhtml +38 -0
- data/doc/layout.xsl +67 -0
- data/doc/license.xml +32 -0
- data/doc/log/changelog.xml +1324 -0
- data/doc/log/changelog.xsl +42 -0
- data/ext/libxml/ruby_xml_document.c +1084 -1057
- data/ext/libxml/ruby_xml_html_parser.c +37 -40
- data/ext/libxml/ruby_xml_input.c +17 -40
- data/ext/libxml/ruby_xml_input.h +2 -2
- data/ext/libxml/ruby_xml_parser.c +151 -151
- data/ext/libxml/ruby_xml_reader.c +910 -893
- data/ext/libxml/ruby_xml_sax_parser.c +174 -174
- data/ext/libxml/ruby_xml_sax_parser.h +12 -12
- data/ext/libxml/ruby_xml_xpointer.h +13 -25
- data/ext/libxml/version.h +2 -2
- data/ext/mingw/libxml_ruby.dll.a +0 -0
- data/ext/mingw/libxml_ruby.so +0 -0
- data/ext/vc/libxml_ruby.vcproj +1 -1
- data/test/model/ruby-lang.html +238 -0
- data/test/tc_html_parser.rb +2 -12
- data/test/tc_reader.rb +87 -87
- metadata +17 -3
- data/test/test.rb +0 -8
@@ -1,1057 +1,1084 @@
|
|
1
|
-
/* $Id: ruby_xml_document.c
|
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 create a document from scratch:
|
12
|
-
*
|
13
|
-
* doc = XML::Document.new()
|
14
|
-
* doc.root = XML::Node.new('root_node')
|
15
|
-
* doc.root << XML::Node.new('elem1')
|
16
|
-
* doc.save('output.xml', format)
|
17
|
-
*
|
18
|
-
* To read a document
|
19
|
-
*
|
20
|
-
* doc = XML::Document.file('my_file')
|
21
|
-
*
|
22
|
-
* To use a parser to read a document:
|
23
|
-
*
|
24
|
-
* parser = XML::Parser.new
|
25
|
-
* parser.file = 'my_file'
|
26
|
-
* doc = parser.parse
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
*
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
*
|
140
|
-
*
|
141
|
-
*
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
Data_Get_Struct(self, xmlDoc, xdoc);
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
#
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
*
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
*
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
*
|
670
|
-
*
|
671
|
-
|
672
|
-
*
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
if (
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
}
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
*
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
}
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
*
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
}
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
*
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
rb_define_method(cXMLDocument, "
|
1052
|
-
rb_define_method(cXMLDocument, "
|
1053
|
-
rb_define_method(cXMLDocument, "
|
1054
|
-
rb_define_method(cXMLDocument, "
|
1055
|
-
rb_define_method(cXMLDocument, "
|
1056
|
-
rb_define_method(cXMLDocument, "
|
1057
|
-
|
1
|
+
/* $Id: ruby_xml_document.c 626 2008-11-22 20:47:07Z 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 create a document from scratch:
|
12
|
+
*
|
13
|
+
* doc = XML::Document.new()
|
14
|
+
* doc.root = XML::Node.new('root_node')
|
15
|
+
* doc.root << XML::Node.new('elem1')
|
16
|
+
* doc.save('output.xml', format)
|
17
|
+
*
|
18
|
+
* To read a document from a file:
|
19
|
+
*
|
20
|
+
* doc = XML::Document.file('my_file')
|
21
|
+
*
|
22
|
+
* To use a parser to read a document:
|
23
|
+
*
|
24
|
+
* parser = XML::Parser.new
|
25
|
+
* parser.file = 'my_file'
|
26
|
+
* doc = parser.parse
|
27
|
+
*
|
28
|
+
* To write a file:
|
29
|
+
*
|
30
|
+
*
|
31
|
+
* doc = XML::Document.new()
|
32
|
+
* doc.root = XML::Node.new('root_node')
|
33
|
+
* root = doc.root
|
34
|
+
*
|
35
|
+
* root << elem1 = XML::Node.new('elem1')
|
36
|
+
* elem1['attr1'] = 'val1'
|
37
|
+
* elem1['attr2'] = 'val2'
|
38
|
+
*
|
39
|
+
* root << elem2 = XML::Node.new('elem2')
|
40
|
+
* elem2['attr1'] = 'val1'
|
41
|
+
* elem2['attr2'] = 'val2'
|
42
|
+
*
|
43
|
+
* root << elem3 = XML::Node.new('elem3')
|
44
|
+
* elem3 << elem4 = XML::Node.new('elem4')
|
45
|
+
* elem3 << elem5 = XML::Node.new('elem5')
|
46
|
+
*
|
47
|
+
* elem5 << elem6 = XML::Node.new('elem6')
|
48
|
+
* elem6 << 'Content for element 6'
|
49
|
+
*
|
50
|
+
* elem3['attr'] = 'baz'
|
51
|
+
*
|
52
|
+
* format = true
|
53
|
+
* doc.save('output.xml', format)
|
54
|
+
*/
|
55
|
+
|
56
|
+
#include <stdarg.h>
|
57
|
+
#include <st.h>
|
58
|
+
#include "ruby_libxml.h"
|
59
|
+
#include "ruby_xml_document.h"
|
60
|
+
|
61
|
+
|
62
|
+
VALUE cXMLDocument;
|
63
|
+
|
64
|
+
void
|
65
|
+
rxml_document_free(xmlDocPtr xdoc) {
|
66
|
+
xdoc->_private = NULL;
|
67
|
+
xmlFreeDoc(xdoc);
|
68
|
+
}
|
69
|
+
|
70
|
+
void
|
71
|
+
rxml_document_mark(xmlDocPtr xdoc) {
|
72
|
+
rb_gc_mark(LIBXML_STATE);
|
73
|
+
}
|
74
|
+
|
75
|
+
VALUE
|
76
|
+
rxml_document_wrap(xmlDocPtr xdoc) {
|
77
|
+
VALUE result;
|
78
|
+
|
79
|
+
// This node is already wrapped
|
80
|
+
if (xdoc->_private != NULL)
|
81
|
+
{
|
82
|
+
result = (VALUE)xdoc->_private;
|
83
|
+
}
|
84
|
+
else
|
85
|
+
{
|
86
|
+
result = Data_Wrap_Struct(cXMLDocument, rxml_document_mark, rxml_document_free, xdoc);
|
87
|
+
xdoc->_private = (void*)result;
|
88
|
+
}
|
89
|
+
|
90
|
+
return result;
|
91
|
+
}
|
92
|
+
|
93
|
+
|
94
|
+
/*
|
95
|
+
* call-seq:
|
96
|
+
* XML::Document.alloc(xml_version = 1.0) -> document
|
97
|
+
*
|
98
|
+
* Alocates a new XML::Document, optionally specifying the
|
99
|
+
* XML version.
|
100
|
+
*/
|
101
|
+
static VALUE
|
102
|
+
rxml_document_alloc(VALUE klass) {
|
103
|
+
return Data_Wrap_Struct(klass, rxml_document_mark, rxml_document_free, NULL);
|
104
|
+
}
|
105
|
+
|
106
|
+
/*
|
107
|
+
* call-seq:
|
108
|
+
* XML::Document.initialize(xml_version = 1.0) -> document
|
109
|
+
*
|
110
|
+
* Initializes a new XML::Document, optionally specifying the
|
111
|
+
* XML version.
|
112
|
+
*/
|
113
|
+
static VALUE
|
114
|
+
rxml_document_initialize(int argc, VALUE *argv, VALUE self) {
|
115
|
+
xmlDocPtr xdoc;
|
116
|
+
VALUE xmlver;
|
117
|
+
|
118
|
+
switch (argc) {
|
119
|
+
case 0:
|
120
|
+
xmlver = rb_str_new2("1.0");
|
121
|
+
break;
|
122
|
+
case 1:
|
123
|
+
rb_scan_args(argc, argv, "01", &xmlver);
|
124
|
+
break;
|
125
|
+
default:
|
126
|
+
rb_raise(rb_eArgError, "wrong number of arguments (need 0 or 1)");
|
127
|
+
}
|
128
|
+
|
129
|
+
Check_Type(xmlver, T_STRING);
|
130
|
+
xdoc = xmlNewDoc((xmlChar*)StringValuePtr(xmlver));
|
131
|
+
xdoc->_private = (void*)self;
|
132
|
+
DATA_PTR(self) = xdoc;
|
133
|
+
|
134
|
+
return self;
|
135
|
+
}
|
136
|
+
|
137
|
+
|
138
|
+
/*
|
139
|
+
* call-seq:
|
140
|
+
* document.compression -> num
|
141
|
+
*
|
142
|
+
* Obtain this document's compression mode identifier.
|
143
|
+
*/
|
144
|
+
static VALUE
|
145
|
+
rxml_document_compression_get(VALUE self) {
|
146
|
+
#ifdef HAVE_ZLIB_H
|
147
|
+
xmlDocPtr xdoc;
|
148
|
+
|
149
|
+
int compmode;
|
150
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
151
|
+
|
152
|
+
compmode = xmlGetDocCompressMode(xdoc);
|
153
|
+
if (compmode == -1)
|
154
|
+
return(Qnil);
|
155
|
+
else
|
156
|
+
return(INT2NUM(compmode));
|
157
|
+
#else
|
158
|
+
rb_warn("libxml not compiled with zlib support");
|
159
|
+
return(Qfalse);
|
160
|
+
#endif
|
161
|
+
}
|
162
|
+
|
163
|
+
|
164
|
+
/*
|
165
|
+
* call-seq:
|
166
|
+
* document.compression = num
|
167
|
+
*
|
168
|
+
* Set this document's compression mode.
|
169
|
+
*/
|
170
|
+
static VALUE
|
171
|
+
rxml_document_compression_set(VALUE self, VALUE num) {
|
172
|
+
#ifdef HAVE_ZLIB_H
|
173
|
+
xmlDocPtr xdoc;
|
174
|
+
|
175
|
+
int compmode;
|
176
|
+
Check_Type(num, T_FIXNUM);
|
177
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
178
|
+
|
179
|
+
if (xdoc == NULL) {
|
180
|
+
return(Qnil);
|
181
|
+
} else {
|
182
|
+
xmlSetDocCompressMode(xdoc, NUM2INT(num));
|
183
|
+
|
184
|
+
compmode = xmlGetDocCompressMode(xdoc);
|
185
|
+
if (compmode == -1)
|
186
|
+
return(Qnil);
|
187
|
+
else
|
188
|
+
return(INT2NUM(compmode));
|
189
|
+
}
|
190
|
+
#else
|
191
|
+
rb_warn("libxml compiled without zlib support");
|
192
|
+
return(Qfalse);
|
193
|
+
#endif
|
194
|
+
}
|
195
|
+
|
196
|
+
|
197
|
+
/*
|
198
|
+
* call-seq:
|
199
|
+
* document.compression? -> (true|false)
|
200
|
+
*
|
201
|
+
* Determine whether this document is compressed.
|
202
|
+
*/
|
203
|
+
static VALUE
|
204
|
+
rxml_document_compression_q(VALUE self) {
|
205
|
+
#ifdef HAVE_ZLIB_H
|
206
|
+
xmlDocPtr xdoc;
|
207
|
+
|
208
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
209
|
+
|
210
|
+
if (xdoc->compression != -1)
|
211
|
+
return(Qtrue);
|
212
|
+
else
|
213
|
+
return(Qfalse);
|
214
|
+
#else
|
215
|
+
rb_warn("libxml compiled without zlib support");
|
216
|
+
return(Qfalse);
|
217
|
+
#endif
|
218
|
+
}
|
219
|
+
|
220
|
+
|
221
|
+
/*
|
222
|
+
* call-seq:
|
223
|
+
* document.child -> node
|
224
|
+
*
|
225
|
+
* Get this document's child node.
|
226
|
+
*/
|
227
|
+
static VALUE
|
228
|
+
rxml_document_child_get(VALUE self) {
|
229
|
+
xmlDocPtr xdoc;
|
230
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
231
|
+
|
232
|
+
if (xdoc->children == NULL)
|
233
|
+
return(Qnil);
|
234
|
+
|
235
|
+
return rxml_node2_wrap(cXMLNode, xdoc->children);
|
236
|
+
}
|
237
|
+
|
238
|
+
|
239
|
+
/*
|
240
|
+
* call-seq:
|
241
|
+
* document.child? -> (true|false)
|
242
|
+
*
|
243
|
+
* Determine whether this document has a child node.
|
244
|
+
*/
|
245
|
+
static VALUE
|
246
|
+
rxml_document_child_q(VALUE self) {
|
247
|
+
xmlDocPtr xdoc;
|
248
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
249
|
+
|
250
|
+
if (xdoc->children == NULL)
|
251
|
+
return(Qfalse);
|
252
|
+
else
|
253
|
+
return(Qtrue);
|
254
|
+
}
|
255
|
+
|
256
|
+
|
257
|
+
/*
|
258
|
+
* call-seq:
|
259
|
+
* document.dump([stream]) -> true
|
260
|
+
*
|
261
|
+
* Dump this document's XML to the specified IO stream.
|
262
|
+
* If no stream is specified, stdout is used.
|
263
|
+
*/
|
264
|
+
static VALUE
|
265
|
+
rxml_document_dump(int argc, VALUE *argv, VALUE self) {
|
266
|
+
OpenFile *fptr;
|
267
|
+
VALUE io;
|
268
|
+
FILE *out;
|
269
|
+
xmlDocPtr xdoc;
|
270
|
+
|
271
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
272
|
+
if (xdoc == NULL)
|
273
|
+
return(Qnil);
|
274
|
+
|
275
|
+
switch (argc) {
|
276
|
+
case 0:
|
277
|
+
io = rb_stdout;
|
278
|
+
break;
|
279
|
+
case 1:
|
280
|
+
io = argv[0];
|
281
|
+
if (!rb_obj_is_kind_of(io, rb_cIO))
|
282
|
+
rb_raise(rb_eTypeError, "need an IO object");
|
283
|
+
break;
|
284
|
+
default:
|
285
|
+
rb_raise(rb_eArgError, "wrong number of arguments (0 or 1)");
|
286
|
+
}
|
287
|
+
|
288
|
+
GetOpenFile(io, fptr);
|
289
|
+
rb_io_check_writable(fptr);
|
290
|
+
out = GetWriteFile(fptr);
|
291
|
+
xmlDocDump(out, xdoc);
|
292
|
+
return(Qtrue);
|
293
|
+
}
|
294
|
+
|
295
|
+
|
296
|
+
/*
|
297
|
+
* call-seq:
|
298
|
+
* document.debug_dump([stream]) -> true
|
299
|
+
*
|
300
|
+
* Debug version of dump.
|
301
|
+
*/
|
302
|
+
static VALUE
|
303
|
+
rxml_document_debug_dump(int argc, VALUE *argv, VALUE self) {
|
304
|
+
#ifdef LIBXML_DEBUG_ENABLED
|
305
|
+
OpenFile *fptr;
|
306
|
+
VALUE io;
|
307
|
+
FILE *out;
|
308
|
+
xmlDocPtr xdoc;
|
309
|
+
|
310
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
311
|
+
if (xdoc == NULL)
|
312
|
+
return(Qnil);
|
313
|
+
|
314
|
+
switch (argc) {
|
315
|
+
case 0:
|
316
|
+
io = rb_stderr;
|
317
|
+
break;
|
318
|
+
case 1:
|
319
|
+
io = argv[0];
|
320
|
+
if (!rb_obj_is_kind_of(io, rb_cIO))
|
321
|
+
rb_raise(rb_eTypeError, "need an IO object");
|
322
|
+
break;
|
323
|
+
default:
|
324
|
+
rb_raise(rb_eArgError, "wrong number of arguments (0 or 1)");
|
325
|
+
}
|
326
|
+
|
327
|
+
GetOpenFile(io, fptr);
|
328
|
+
rb_io_check_writable(fptr);
|
329
|
+
out = GetWriteFile(fptr);
|
330
|
+
xmlDebugDumpDocument(out, xdoc);
|
331
|
+
return(Qtrue);
|
332
|
+
#else
|
333
|
+
rb_warn("libxml was compiled without debugging support. Please recompile libxml and ruby-libxml");
|
334
|
+
return(Qfalse);
|
335
|
+
#endif
|
336
|
+
}
|
337
|
+
|
338
|
+
|
339
|
+
/*
|
340
|
+
* call-seq:
|
341
|
+
* document.debug_dump_head([stream]) -> true
|
342
|
+
*
|
343
|
+
* Debug-dump this document's header to the specified IO stream.
|
344
|
+
* If no stream is specified, stdout is used.
|
345
|
+
*/
|
346
|
+
static VALUE
|
347
|
+
rxml_document_debug_dump_head(int argc, VALUE *argv, VALUE self) {
|
348
|
+
#ifdef LIBXML_DEBUG_ENABLED
|
349
|
+
OpenFile *fptr;
|
350
|
+
VALUE io;
|
351
|
+
FILE *out;
|
352
|
+
xmlDocPtr xdoc;
|
353
|
+
|
354
|
+
|
355
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
356
|
+
if (xdoc == NULL)
|
357
|
+
return(Qnil);
|
358
|
+
|
359
|
+
switch (argc) {
|
360
|
+
case 0:
|
361
|
+
io = rb_stdout;
|
362
|
+
break;
|
363
|
+
case 1:
|
364
|
+
io = argv[0];
|
365
|
+
if (!rb_obj_is_kind_of(io, rb_cIO))
|
366
|
+
rb_raise(rb_eTypeError, "need an IO object");
|
367
|
+
break;
|
368
|
+
default:
|
369
|
+
rb_raise(rb_eArgError, "wrong number of arguments (0 or 1)");
|
370
|
+
}
|
371
|
+
|
372
|
+
GetOpenFile(io, fptr);
|
373
|
+
rb_io_check_writable(fptr);
|
374
|
+
out = GetWriteFile(fptr);
|
375
|
+
xmlDebugDumpDocumentHead(out, xdoc);
|
376
|
+
return(Qtrue);
|
377
|
+
#else
|
378
|
+
rb_warn("libxml was compiled without debugging support. Please recompile libxml and ruby-libxml");
|
379
|
+
return(Qfalse);
|
380
|
+
#endif
|
381
|
+
}
|
382
|
+
|
383
|
+
|
384
|
+
/*
|
385
|
+
* call-seq:
|
386
|
+
* document.format_dump([stream], [spacing]) -> true
|
387
|
+
*
|
388
|
+
* Dump this document's formatted XML to the specified IO stream.
|
389
|
+
* If no stream is specified, stdout is used. If spacing is
|
390
|
+
* specified, it must be a boolean that determines whether
|
391
|
+
* spacing is used.
|
392
|
+
*/
|
393
|
+
static VALUE
|
394
|
+
rxml_document_format_dump(int argc, VALUE *argv, VALUE self) {
|
395
|
+
OpenFile *fptr;
|
396
|
+
VALUE bool, io;
|
397
|
+
FILE *out;
|
398
|
+
xmlDocPtr xdoc;
|
399
|
+
|
400
|
+
int size, spacing;
|
401
|
+
|
402
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
403
|
+
if (xdoc == NULL)
|
404
|
+
return(Qnil);
|
405
|
+
|
406
|
+
switch (argc) {
|
407
|
+
case 0:
|
408
|
+
io = rb_stdout;
|
409
|
+
spacing = 1;
|
410
|
+
break;
|
411
|
+
case 1:
|
412
|
+
io = argv[0];
|
413
|
+
if (!rb_obj_is_kind_of(io, rb_cIO))
|
414
|
+
rb_raise(rb_eTypeError, "need an IO object");
|
415
|
+
spacing = 1;
|
416
|
+
break;
|
417
|
+
case 2:
|
418
|
+
io = argv[0];
|
419
|
+
if (!rb_obj_is_kind_of(io, rb_cIO))
|
420
|
+
rb_raise(rb_eTypeError, "need an IO object");
|
421
|
+
bool = argv[1];
|
422
|
+
if (TYPE(bool) == T_TRUE)
|
423
|
+
spacing = 1;
|
424
|
+
else if (TYPE(bool) == T_FALSE)
|
425
|
+
spacing = 0;
|
426
|
+
else
|
427
|
+
rb_raise(rb_eTypeError, "incorect argument type, second argument must be bool");
|
428
|
+
|
429
|
+
break;
|
430
|
+
default:
|
431
|
+
rb_raise(rb_eArgError, "wrong number of arguments (0 or 1)");
|
432
|
+
}
|
433
|
+
|
434
|
+
GetOpenFile(io, fptr);
|
435
|
+
rb_io_check_writable(fptr);
|
436
|
+
out = GetWriteFile(fptr);
|
437
|
+
size = xmlDocFormatDump(out, xdoc, spacing);
|
438
|
+
return(INT2NUM(size));
|
439
|
+
}
|
440
|
+
|
441
|
+
|
442
|
+
/*
|
443
|
+
* call-seq:
|
444
|
+
* document.debug_format_dump([stream]) -> true
|
445
|
+
*
|
446
|
+
* *Deprecated* in favour of format_dump.
|
447
|
+
*/
|
448
|
+
static VALUE
|
449
|
+
rxml_document_debug_format_dump(int argc, VALUE *argv, VALUE self) {
|
450
|
+
rb_warn("debug_format_dump has been deprecaited, use format_dump instead");
|
451
|
+
return(rxml_document_format_dump(argc, argv, self));
|
452
|
+
}
|
453
|
+
|
454
|
+
|
455
|
+
/*
|
456
|
+
* call-seq:
|
457
|
+
* document.encoding -> "encoding"
|
458
|
+
*
|
459
|
+
* Obtain the encoding specified by this document.
|
460
|
+
*/
|
461
|
+
static VALUE
|
462
|
+
rxml_document_encoding_get(VALUE self) {
|
463
|
+
xmlDocPtr xdoc;
|
464
|
+
|
465
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
466
|
+
if (xdoc->encoding == NULL)
|
467
|
+
return(Qnil);
|
468
|
+
else
|
469
|
+
return(rb_str_new2((const char*)xdoc->encoding));
|
470
|
+
}
|
471
|
+
|
472
|
+
|
473
|
+
/*
|
474
|
+
* call-seq:
|
475
|
+
* document.encoding = "encoding"
|
476
|
+
*
|
477
|
+
* Set the encoding for this document.
|
478
|
+
*/
|
479
|
+
static VALUE
|
480
|
+
rxml_document_encoding_set(VALUE self, VALUE encoding) {
|
481
|
+
xmlDocPtr xdoc;
|
482
|
+
|
483
|
+
|
484
|
+
Check_Type(encoding, T_STRING);
|
485
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
486
|
+
xdoc->encoding = xmlStrdup(StringValuePtr(encoding));
|
487
|
+
return(rxml_document_encoding_get(self));
|
488
|
+
}
|
489
|
+
|
490
|
+
/*
|
491
|
+
* call-seq:
|
492
|
+
* document.last -> node
|
493
|
+
*
|
494
|
+
* Obtain the last node.
|
495
|
+
*/
|
496
|
+
static VALUE
|
497
|
+
rxml_document_last_get(VALUE self) {
|
498
|
+
xmlDocPtr xdoc;
|
499
|
+
|
500
|
+
|
501
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
502
|
+
|
503
|
+
if (xdoc->last == NULL)
|
504
|
+
return(Qnil);
|
505
|
+
|
506
|
+
return rxml_node2_wrap(cXMLNode, xdoc->last);
|
507
|
+
}
|
508
|
+
|
509
|
+
|
510
|
+
/*
|
511
|
+
* call-seq:
|
512
|
+
* document.last? -> (true|false)
|
513
|
+
*
|
514
|
+
* Determine whether there is a last node.
|
515
|
+
*/
|
516
|
+
static VALUE
|
517
|
+
rxml_document_last_q(VALUE self) {
|
518
|
+
xmlDocPtr xdoc;
|
519
|
+
|
520
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
521
|
+
|
522
|
+
if (xdoc->last == NULL)
|
523
|
+
return(Qfalse);
|
524
|
+
else
|
525
|
+
return(Qtrue);
|
526
|
+
}
|
527
|
+
|
528
|
+
|
529
|
+
/*
|
530
|
+
* call-seq:
|
531
|
+
* document.next -> node
|
532
|
+
*
|
533
|
+
* Obtain the next node.
|
534
|
+
*/
|
535
|
+
static VALUE
|
536
|
+
rxml_document_next_get(VALUE self) {
|
537
|
+
xmlDocPtr xdoc;
|
538
|
+
|
539
|
+
|
540
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
541
|
+
|
542
|
+
if (xdoc->next == NULL)
|
543
|
+
return(Qnil);
|
544
|
+
|
545
|
+
return rxml_node2_wrap(cXMLNode, xdoc->next);
|
546
|
+
}
|
547
|
+
|
548
|
+
|
549
|
+
/*
|
550
|
+
* call-seq:
|
551
|
+
* document.next? -> (true|false)
|
552
|
+
*
|
553
|
+
* Determine whether there is a next node.
|
554
|
+
*/
|
555
|
+
static VALUE
|
556
|
+
rxml_document_next_q(VALUE self) {
|
557
|
+
xmlDocPtr xdoc;
|
558
|
+
|
559
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
560
|
+
|
561
|
+
if (xdoc->next == NULL)
|
562
|
+
return(Qfalse);
|
563
|
+
else
|
564
|
+
return(Qtrue);
|
565
|
+
}
|
566
|
+
|
567
|
+
|
568
|
+
/*
|
569
|
+
* call-seq:
|
570
|
+
* document.parent -> node
|
571
|
+
*
|
572
|
+
* Obtain the parent node.
|
573
|
+
*/
|
574
|
+
static VALUE
|
575
|
+
rxml_document_parent_get(VALUE self) {
|
576
|
+
xmlDocPtr xdoc;
|
577
|
+
|
578
|
+
|
579
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
580
|
+
|
581
|
+
if (xdoc->parent == NULL)
|
582
|
+
return(Qnil);
|
583
|
+
|
584
|
+
return rxml_node2_wrap(cXMLNode, xdoc->parent);
|
585
|
+
}
|
586
|
+
|
587
|
+
|
588
|
+
/*
|
589
|
+
* call-seq:
|
590
|
+
* document.parent? -> (true|false)
|
591
|
+
*
|
592
|
+
* Determine whether there is a parent node.
|
593
|
+
*/
|
594
|
+
static VALUE
|
595
|
+
rxml_document_parent_q(VALUE self) {
|
596
|
+
xmlDocPtr xdoc;
|
597
|
+
|
598
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
599
|
+
|
600
|
+
if (xdoc->parent == NULL)
|
601
|
+
return(Qfalse);
|
602
|
+
else
|
603
|
+
return(Qtrue);
|
604
|
+
}
|
605
|
+
|
606
|
+
|
607
|
+
/*
|
608
|
+
* call-seq:
|
609
|
+
* document.prev -> node
|
610
|
+
*
|
611
|
+
* Obtain the previous node.
|
612
|
+
*/
|
613
|
+
static VALUE
|
614
|
+
rxml_document_prev_get(VALUE self) {
|
615
|
+
xmlDocPtr xdoc;
|
616
|
+
|
617
|
+
|
618
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
619
|
+
|
620
|
+
if (xdoc->prev == NULL)
|
621
|
+
return(Qnil);
|
622
|
+
|
623
|
+
return rxml_node2_wrap(cXMLNode, xdoc->prev);
|
624
|
+
}
|
625
|
+
|
626
|
+
|
627
|
+
/*
|
628
|
+
* call-seq:
|
629
|
+
* document.prev? -> (true|false)
|
630
|
+
*
|
631
|
+
* Determine whether there is a previous node.
|
632
|
+
*/
|
633
|
+
static VALUE
|
634
|
+
rxml_document_prev_q(VALUE self) {
|
635
|
+
xmlDocPtr xdoc;
|
636
|
+
|
637
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
638
|
+
|
639
|
+
if (xdoc->prev == NULL)
|
640
|
+
return(Qfalse);
|
641
|
+
else
|
642
|
+
return(Qtrue);
|
643
|
+
}
|
644
|
+
|
645
|
+
|
646
|
+
/*
|
647
|
+
* call-seq:
|
648
|
+
* document.root -> node
|
649
|
+
*
|
650
|
+
* Obtain the root node.
|
651
|
+
*/
|
652
|
+
static VALUE
|
653
|
+
rxml_document_root_get(VALUE self) {
|
654
|
+
xmlDocPtr xdoc;
|
655
|
+
|
656
|
+
xmlNodePtr root;
|
657
|
+
|
658
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
659
|
+
root = xmlDocGetRootElement(xdoc);
|
660
|
+
|
661
|
+
if (root == NULL)
|
662
|
+
return(Qnil);
|
663
|
+
|
664
|
+
return rxml_node2_wrap(cXMLNode, root);
|
665
|
+
}
|
666
|
+
|
667
|
+
|
668
|
+
/*
|
669
|
+
* call-seq:
|
670
|
+
* document.root = node
|
671
|
+
*
|
672
|
+
* Set the root node.
|
673
|
+
*/
|
674
|
+
static VALUE
|
675
|
+
rxml_document_root_set(VALUE self, VALUE node) {
|
676
|
+
xmlDocPtr xdoc;
|
677
|
+
xmlNodePtr xroot, xnode;
|
678
|
+
|
679
|
+
if (rb_obj_is_kind_of(node, cXMLNode) == Qfalse)
|
680
|
+
rb_raise(rb_eTypeError, "must pass an XML::Node type object");
|
681
|
+
|
682
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
683
|
+
Data_Get_Struct(node, xmlNode, xnode);
|
684
|
+
xroot = xmlDocSetRootElement(xdoc, xnode);
|
685
|
+
if (xroot == NULL)
|
686
|
+
return(Qnil);
|
687
|
+
|
688
|
+
return rxml_node2_wrap(cXMLNode, xroot);
|
689
|
+
}
|
690
|
+
|
691
|
+
|
692
|
+
/*
|
693
|
+
* call-seq:
|
694
|
+
* document.save(filename, format = false) -> int
|
695
|
+
*
|
696
|
+
* Save this document to the file given by filename,
|
697
|
+
* optionally formatting the output.
|
698
|
+
|
699
|
+
* Parameters:
|
700
|
+
* filename: The filename or URL of the new document
|
701
|
+
* format: Specifies whether formatting spaces should be added.
|
702
|
+
* returns: The number of bytes written or -1 in case of error.
|
703
|
+
*/
|
704
|
+
static VALUE
|
705
|
+
rxml_document_save(int argc, VALUE *argv, VALUE self) {
|
706
|
+
xmlDocPtr xdoc;
|
707
|
+
|
708
|
+
const char *filename;
|
709
|
+
int format = 0;
|
710
|
+
int len;
|
711
|
+
|
712
|
+
if (argc <1 || argc > 2)
|
713
|
+
rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
|
714
|
+
|
715
|
+
Check_Type(argv[0], T_STRING);
|
716
|
+
filename = StringValuePtr(argv[0]);
|
717
|
+
|
718
|
+
if (argc == 2)
|
719
|
+
{
|
720
|
+
switch (TYPE(argv[1])) {
|
721
|
+
case T_TRUE:
|
722
|
+
format = 1;
|
723
|
+
break;
|
724
|
+
case T_FALSE:
|
725
|
+
format = 0;
|
726
|
+
break;
|
727
|
+
default:
|
728
|
+
rb_raise(rb_eArgError, "The second parameter (format) must be true or false");
|
729
|
+
}
|
730
|
+
}
|
731
|
+
|
732
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
733
|
+
len = xmlSaveFormatFileEnc(filename, xdoc, (const char*)xdoc->encoding, format);
|
734
|
+
|
735
|
+
if (len == -1)
|
736
|
+
rb_raise(rb_eIOError, "Could not write document");
|
737
|
+
else
|
738
|
+
return(INT2NUM(len));
|
739
|
+
}
|
740
|
+
|
741
|
+
|
742
|
+
/*
|
743
|
+
* call-seq:
|
744
|
+
* document.standalone? -> (true|false)
|
745
|
+
*
|
746
|
+
* Determine whether this is a standalone document.
|
747
|
+
*/
|
748
|
+
static VALUE
|
749
|
+
rxml_document_standalone_q(VALUE self) {
|
750
|
+
xmlDocPtr xdoc;
|
751
|
+
|
752
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
753
|
+
if (xdoc->standalone)
|
754
|
+
return(Qtrue);
|
755
|
+
else
|
756
|
+
return(Qfalse);
|
757
|
+
}
|
758
|
+
|
759
|
+
|
760
|
+
/*
|
761
|
+
* call-seq:
|
762
|
+
* document.to_s({format=true,encoding) -> "xml"
|
763
|
+
*
|
764
|
+
* Coerce this document to a string representation
|
765
|
+
* of it's XML. The default is to pretty format, but this
|
766
|
+
* depends Parser#indent_tree_output==true or
|
767
|
+
* Parser#default_keep_blanks==false.
|
768
|
+
*
|
769
|
+
* The encoding is not applied to the document, but is
|
770
|
+
* encoding target of the resulting string.
|
771
|
+
*/
|
772
|
+
static VALUE
|
773
|
+
rxml_document_to_s(int argc, VALUE *argv, VALUE self) {
|
774
|
+
xmlDocPtr xdoc;
|
775
|
+
|
776
|
+
xmlChar *result, *encoding=NULL;
|
777
|
+
int format, len;
|
778
|
+
VALUE rresult;
|
779
|
+
|
780
|
+
switch (argc) {
|
781
|
+
case 0:
|
782
|
+
format = 1;
|
783
|
+
break;
|
784
|
+
case 2:
|
785
|
+
if (TYPE(argv[1]) == T_STRING)
|
786
|
+
encoding=(xmlChar *)StringValuePtr(argv[1]);
|
787
|
+
case 1:
|
788
|
+
if (TYPE(argv[0]) == T_TRUE)
|
789
|
+
format = 1;
|
790
|
+
else if (TYPE(argv[0]) == T_FALSE)
|
791
|
+
format = 0;
|
792
|
+
else
|
793
|
+
rb_raise(rb_eTypeError, "wrong type of argument, must be bool");
|
794
|
+
break;
|
795
|
+
default:
|
796
|
+
rb_raise(rb_eArgError, "wrong number of arguments (0 or 1)");
|
797
|
+
}
|
798
|
+
|
799
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
800
|
+
if (xdoc == NULL) {
|
801
|
+
return(Qnil);
|
802
|
+
} else if (encoding != NULL) {
|
803
|
+
if (format) {
|
804
|
+
xmlDocDumpFormatMemoryEnc(xdoc, &result, &len,
|
805
|
+
(const char*)encoding, format);
|
806
|
+
} else {
|
807
|
+
xmlDocDumpMemoryEnc(xdoc, &result, &len,
|
808
|
+
(const char *)encoding);
|
809
|
+
}
|
810
|
+
} else {
|
811
|
+
if (format)
|
812
|
+
xmlDocDumpFormatMemory(xdoc, &result, &len, format);
|
813
|
+
else
|
814
|
+
xmlDocDumpMemory(xdoc, &result, &len);
|
815
|
+
}
|
816
|
+
rresult=rb_str_new((const char*)result,len);
|
817
|
+
xmlFree(result);
|
818
|
+
return rresult;
|
819
|
+
}
|
820
|
+
|
821
|
+
|
822
|
+
/*
|
823
|
+
* call-seq:
|
824
|
+
* document.url -> "url"
|
825
|
+
*
|
826
|
+
* Obtain this document's source URL, if any.
|
827
|
+
*/
|
828
|
+
static VALUE
|
829
|
+
rxml_document_url_get(VALUE self) {
|
830
|
+
xmlDocPtr xdoc;
|
831
|
+
|
832
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
833
|
+
if (xdoc->URL == NULL)
|
834
|
+
return(Qnil);
|
835
|
+
else
|
836
|
+
return(rb_str_new2((const char*)xdoc->URL));
|
837
|
+
}
|
838
|
+
|
839
|
+
|
840
|
+
/*
|
841
|
+
* call-seq:
|
842
|
+
* document.version -> "version"
|
843
|
+
*
|
844
|
+
* Obtain the XML version specified by this document.
|
845
|
+
*/
|
846
|
+
static VALUE
|
847
|
+
rxml_document_version_get(VALUE self) {
|
848
|
+
xmlDocPtr xdoc;
|
849
|
+
|
850
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
851
|
+
if (xdoc->version == NULL)
|
852
|
+
return(Qnil);
|
853
|
+
else
|
854
|
+
return(rb_str_new2((const char*)xdoc->version));
|
855
|
+
}
|
856
|
+
|
857
|
+
|
858
|
+
/*
|
859
|
+
* call-seq:
|
860
|
+
* document.xinclude -> num
|
861
|
+
*
|
862
|
+
* Process xinclude directives in this document.
|
863
|
+
*/
|
864
|
+
static VALUE
|
865
|
+
rxml_document_xinclude(VALUE self) {
|
866
|
+
#ifdef LIBXML_XINCLUDE_ENABLED
|
867
|
+
xmlDocPtr xdoc;
|
868
|
+
|
869
|
+
int ret;
|
870
|
+
|
871
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
872
|
+
ret = xmlXIncludeProcess(xdoc);
|
873
|
+
if (ret >= 0)
|
874
|
+
{
|
875
|
+
return(INT2NUM(ret));
|
876
|
+
}
|
877
|
+
else
|
878
|
+
{
|
879
|
+
rxml_raise(&xmlLastError);
|
880
|
+
return Qnil;
|
881
|
+
}
|
882
|
+
#else
|
883
|
+
rb_warn("libxml was compiled without XInclude support. Please recompile libxml and ruby-libxml");
|
884
|
+
return(Qfalse);
|
885
|
+
#endif
|
886
|
+
}
|
887
|
+
|
888
|
+
void
|
889
|
+
LibXML_validity_error(void * ctxt, const char * msg, va_list ap)
|
890
|
+
{
|
891
|
+
if (rb_block_given_p()) {
|
892
|
+
char buff[1024];
|
893
|
+
snprintf(buff, 1024, msg, ap);
|
894
|
+
rb_yield(rb_ary_new3(2, rb_str_new2(buff), Qtrue));
|
895
|
+
} else {
|
896
|
+
fprintf(stderr, "error -- found validity error: ");
|
897
|
+
fprintf(stderr, msg, ap);
|
898
|
+
}
|
899
|
+
}
|
900
|
+
|
901
|
+
void
|
902
|
+
LibXML_validity_warning(void * ctxt, const char * msg, va_list ap)
|
903
|
+
{
|
904
|
+
if (rb_block_given_p()) {
|
905
|
+
char buff[1024];
|
906
|
+
snprintf(buff, 1024, msg, ap);
|
907
|
+
rb_yield(rb_ary_new3(2, rb_str_new2(buff), Qfalse));
|
908
|
+
} else {
|
909
|
+
fprintf(stderr, "warning -- found validity error: ");
|
910
|
+
fprintf(stderr, msg, ap);
|
911
|
+
}
|
912
|
+
}
|
913
|
+
|
914
|
+
/*
|
915
|
+
* call-seq:
|
916
|
+
* document.validate_schema(schema) -> (true|false)
|
917
|
+
*
|
918
|
+
* Validate this document against the specified XML::Schema.
|
919
|
+
*
|
920
|
+
* If a block is provided it is used as an error handler for validaten errors.
|
921
|
+
* The block is called with two argument, the message and a flag indication
|
922
|
+
* if the message is an error (true) or a warning (false).
|
923
|
+
*/
|
924
|
+
static VALUE
|
925
|
+
rxml_document_validate_schema(VALUE self, VALUE schema) {
|
926
|
+
xmlSchemaValidCtxtPtr vptr;
|
927
|
+
xmlDocPtr xdoc;
|
928
|
+
xmlSchemaPtr xschema;
|
929
|
+
int is_invalid;
|
930
|
+
|
931
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
932
|
+
Data_Get_Struct(schema, xmlSchema, xschema);
|
933
|
+
|
934
|
+
vptr = xmlSchemaNewValidCtxt(xschema);
|
935
|
+
|
936
|
+
xmlSchemaSetValidErrors(vptr, (xmlSchemaValidityErrorFunc)LibXML_validity_error,
|
937
|
+
(xmlSchemaValidityWarningFunc)LibXML_validity_warning, NULL);
|
938
|
+
|
939
|
+
is_invalid = xmlSchemaValidateDoc(vptr, xdoc);
|
940
|
+
xmlSchemaFreeValidCtxt(vptr);
|
941
|
+
if (is_invalid)
|
942
|
+
{
|
943
|
+
rxml_raise(&xmlLastError);
|
944
|
+
return Qfalse;
|
945
|
+
}
|
946
|
+
else
|
947
|
+
{
|
948
|
+
return Qtrue;
|
949
|
+
}
|
950
|
+
}
|
951
|
+
|
952
|
+
/*
|
953
|
+
* call-seq:
|
954
|
+
* document.validate_schema(relaxng) -> (true|false)
|
955
|
+
*
|
956
|
+
* Validate this document against the specified XML::RelaxNG.
|
957
|
+
*
|
958
|
+
* If a block is provided it is used as an error handler for validaten errors.
|
959
|
+
* The block is called with two argument, the message and a flag indication
|
960
|
+
* if the message is an error (true) or a warning (false).
|
961
|
+
*/
|
962
|
+
static VALUE
|
963
|
+
rxml_document_validate_relaxng(VALUE self, VALUE relaxng) {
|
964
|
+
xmlRelaxNGValidCtxtPtr vptr;
|
965
|
+
xmlDocPtr xdoc;
|
966
|
+
xmlRelaxNGPtr xrelaxng;
|
967
|
+
int is_invalid;
|
968
|
+
|
969
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
970
|
+
Data_Get_Struct(relaxng, xmlRelaxNG, xrelaxng);
|
971
|
+
|
972
|
+
vptr = xmlRelaxNGNewValidCtxt(xrelaxng);
|
973
|
+
|
974
|
+
xmlRelaxNGSetValidErrors(vptr, (xmlRelaxNGValidityErrorFunc)LibXML_validity_error,
|
975
|
+
(xmlRelaxNGValidityWarningFunc)LibXML_validity_warning, NULL);
|
976
|
+
|
977
|
+
is_invalid = xmlRelaxNGValidateDoc(vptr, xdoc);
|
978
|
+
xmlRelaxNGFreeValidCtxt(vptr);
|
979
|
+
if (is_invalid)
|
980
|
+
{
|
981
|
+
rxml_raise(&xmlLastError);
|
982
|
+
return Qfalse;
|
983
|
+
} else
|
984
|
+
{
|
985
|
+
return Qtrue;
|
986
|
+
}
|
987
|
+
}
|
988
|
+
|
989
|
+
|
990
|
+
/*
|
991
|
+
* call-seq:
|
992
|
+
* document.validate(dtd) -> (true|false)
|
993
|
+
*
|
994
|
+
* Validate this document against the specified XML::DTD.
|
995
|
+
*/
|
996
|
+
static VALUE
|
997
|
+
rxml_document_validate_dtd(VALUE self, VALUE dtd) {
|
998
|
+
VALUE error = Qnil;
|
999
|
+
xmlValidCtxt ctxt;
|
1000
|
+
xmlDocPtr xdoc;
|
1001
|
+
xmlDtdPtr xdtd;
|
1002
|
+
|
1003
|
+
Data_Get_Struct(self, xmlDoc, xdoc);
|
1004
|
+
Data_Get_Struct(dtd, xmlDtd, xdtd);
|
1005
|
+
|
1006
|
+
ctxt.userData = &error;
|
1007
|
+
ctxt.error = (xmlValidityErrorFunc)LibXML_validity_error;
|
1008
|
+
ctxt.warning = (xmlValidityWarningFunc)LibXML_validity_warning;
|
1009
|
+
|
1010
|
+
ctxt.nodeNr = 0;
|
1011
|
+
ctxt.nodeTab = NULL;
|
1012
|
+
ctxt.vstateNr = 0;
|
1013
|
+
ctxt.vstateTab = NULL;
|
1014
|
+
|
1015
|
+
if (xmlValidateDtd(&ctxt, xdoc, xdtd))
|
1016
|
+
{
|
1017
|
+
return(Qtrue);
|
1018
|
+
}
|
1019
|
+
else
|
1020
|
+
{
|
1021
|
+
rxml_raise(&xmlLastError);
|
1022
|
+
return Qfalse;
|
1023
|
+
}
|
1024
|
+
}
|
1025
|
+
|
1026
|
+
|
1027
|
+
/*
|
1028
|
+
* call-seq:
|
1029
|
+
* document.reader -> reader
|
1030
|
+
*
|
1031
|
+
* Create a XML::Reader from the document. This is a shortcut to
|
1032
|
+
* XML::Reader.walker().
|
1033
|
+
*/
|
1034
|
+
static VALUE
|
1035
|
+
rxml_document_reader(VALUE self)
|
1036
|
+
{
|
1037
|
+
return rxml_reader_new_walker(cXMLReader, self);
|
1038
|
+
}
|
1039
|
+
|
1040
|
+
// Rdoc needs to know
|
1041
|
+
#ifdef RDOC_NEVER_DEFINED
|
1042
|
+
mLibXML = rb_define_module("LibXML");
|
1043
|
+
mXML = rb_define_module_under(mLibXML, "XML");
|
1044
|
+
#endif
|
1045
|
+
|
1046
|
+
void
|
1047
|
+
ruby_init_xml_document(void) {
|
1048
|
+
cXMLDocument = rb_define_class_under(mXML, "Document", rb_cObject);
|
1049
|
+
rb_define_alloc_func(cXMLDocument, rxml_document_alloc);
|
1050
|
+
|
1051
|
+
rb_define_method(cXMLDocument, "initialize", rxml_document_initialize, -1);
|
1052
|
+
rb_define_method(cXMLDocument, "child", rxml_document_child_get, 0);
|
1053
|
+
rb_define_method(cXMLDocument, "child?", rxml_document_child_q, 0);
|
1054
|
+
rb_define_method(cXMLDocument, "compression", rxml_document_compression_get, 0);
|
1055
|
+
rb_define_method(cXMLDocument, "compression=", rxml_document_compression_set, 1);
|
1056
|
+
rb_define_method(cXMLDocument, "compression?", rxml_document_compression_q, 0);
|
1057
|
+
rb_define_method(cXMLDocument, "dump", rxml_document_dump, -1);
|
1058
|
+
rb_define_method(cXMLDocument, "debug_dump", rxml_document_debug_dump, -1);
|
1059
|
+
rb_define_method(cXMLDocument, "debug_dump_head", rxml_document_debug_dump_head, -1);
|
1060
|
+
rb_define_method(cXMLDocument, "debug_format_dump", rxml_document_debug_format_dump, -1);
|
1061
|
+
rb_define_method(cXMLDocument, "encoding", rxml_document_encoding_get, 0);
|
1062
|
+
rb_define_method(cXMLDocument, "encoding=", rxml_document_encoding_set, 1);
|
1063
|
+
rb_define_method(cXMLDocument, "format_dump", rxml_document_format_dump, -1);
|
1064
|
+
rb_define_method(cXMLDocument, "last", rxml_document_last_get, 0);
|
1065
|
+
rb_define_method(cXMLDocument, "last?", rxml_document_last_q, 0);
|
1066
|
+
rb_define_method(cXMLDocument, "next", rxml_document_next_get, 0);
|
1067
|
+
rb_define_method(cXMLDocument, "next?", rxml_document_next_q, 0);
|
1068
|
+
rb_define_method(cXMLDocument, "parent", rxml_document_parent_get, 0);
|
1069
|
+
rb_define_method(cXMLDocument, "parent?", rxml_document_parent_q, 0);
|
1070
|
+
rb_define_method(cXMLDocument, "prev", rxml_document_prev_get, 0);
|
1071
|
+
rb_define_method(cXMLDocument, "prev?", rxml_document_prev_q, 0);
|
1072
|
+
rb_define_method(cXMLDocument, "root", rxml_document_root_get, 0);
|
1073
|
+
rb_define_method(cXMLDocument, "root=", rxml_document_root_set, 1);
|
1074
|
+
rb_define_method(cXMLDocument, "save", rxml_document_save, -1);
|
1075
|
+
rb_define_method(cXMLDocument, "standalone?", rxml_document_standalone_q, 0);
|
1076
|
+
rb_define_method(cXMLDocument, "to_s", rxml_document_to_s, -1);
|
1077
|
+
rb_define_method(cXMLDocument, "url", rxml_document_url_get, 0);
|
1078
|
+
rb_define_method(cXMLDocument, "version", rxml_document_version_get, 0);
|
1079
|
+
rb_define_method(cXMLDocument, "xinclude", rxml_document_xinclude, 0);
|
1080
|
+
rb_define_method(cXMLDocument, "validate", rxml_document_validate_dtd, 1);
|
1081
|
+
rb_define_method(cXMLDocument, "validate_schema", rxml_document_validate_schema, 1);
|
1082
|
+
rb_define_method(cXMLDocument, "validate_relaxng", rxml_document_validate_relaxng, 1);
|
1083
|
+
rb_define_method(cXMLDocument, "reader", rxml_document_reader, 0);
|
1084
|
+
}
|