aboutsummaryrefslogtreecommitdiff
path: root/doc/expat.texi
blob: 993c1f233b243cada027a7a89a02b6d7bd7bdd73 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
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
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
@c This file is part of the Gamma manual.
@c Copyright (C) 2010 Sergey Poznyakoff
@c See gamma.texi for copying conditions.
@c *******************************************************************
@cindex XML
@cindex Expat
@cindex libexpat
The @samp{(gamma expat)} module provides interface to
@command{libexpat}, a library for parsing @acronym{XML} documents.
See @uref{http://expat.sourceforge.net}, for a description of the
library.

Usage:

@lisp
(use-modules ((gamma expat)))
@end lisp

@menu
* expat basics::
* creating parsers::
* parsing::
* errors::
* handlers::
* miscellaneous functions::
@end menu

@node expat basics
@section Expat Basics
@cindex expat, basics
@cindex callback, expat
@cindex handlers, expat
Parsing of @acronym{XML} documents using Expat is based on
user-defined callback functions.  You create a @dfn{parser}
object, and associate @dfn{callback} (or @dfn{handler}) functions with
the events he is interested in.  Such events may be, for instance,
encountering of a open or closing tag, encountering of a comment
block, etc.  Once the parser object is ready, you start feeding the
document to it.  As the parser recognizes @acronym{XML} constructs, it
calls the callbacks that are registered for them.

@cindex parser, creating
Parsers are created using @code{xml-make-parser} function.  In the
simplest case, it takes no arguments, e.g.:

@lisp
(let ((parser (xml-make-parser)))
  @dots{}
@end lisp

The function @code{xml-parse} takes the parser as its argument, reads
the document from the current input stream and feeds it to the parser.
Thus, the simplest program for parsing @acronym{XML} documents is:

@flindex xmlck.scm, example
@anchor{xmlck.scm}
@lisp
(use-modules ((gamma expat)))
(xml-parse (xml-make-parser))
@end lisp

This program is perhaps not so useful, but you may already use it to
check whether its input is a correctly formed @acronym{XML} document.
If @code{xml-parse} encounters an error, it signals the
@code{gamma-xml-error} error.  @xref{errors, error handling}, for a
discussion on how to handle it.

@cindex handlers, expat
The @code{xml-make-parser} function takes optional arguments, which
allow to set callback functions for the new parser.  For example, the
following code sets function @samp{elt-start} as a handler for
start elements:

@lisp
(xml-make-parser #:start-element-handler elt-start)
@end lisp

The @code{#:start-element-handler} keyword informs the function that
the argument following it is a handler for start @acronym{XML} documents.
Any number of handlers may be set this way, e.g.:

@lisp
(xml-make-parser #:start-element-handler elt-start
                 #:end-element-handler elt-end
                 #:comment-handler comment)
@end lisp

Definitions of particular handler functions differ depending on their
purpose, i.e. on the event they are defined to handle.  For example,
a start element handler must be defined as having two arguments.
First of them is the name of the tag, and the second one is a list of
attributes supplied for that tag.  Thus, for example, the following
start handler prints the tag and the number of attributes:

@lisp
(define (elt-start name attrs)
  (format #t "~A (~A)~%" name (length attrs)))
@end lisp

For a detailed description of all available handlers and handler
keywords, see @ref{handlers}.

To further improve our example, suppose you need a program that will
take an @acronym{XML} document as its input and create a description
of its structure on output, showing element nesting levels by
indenting their description.  Here is how to write it.

First, define handlers for start and end elements.  Start element
handler will print two indenting spaces for each level of ancestor
elements, followed by the element name and its attributes and a
newline.  It will then increase the global level variable:

@lisp
(define level 0)

(define (elt-start name attrs)
  (display (make-string (* 2 level) #\space))
  (display name)
  (for-each
   (lambda (x)
    (display " ")
    (display (car x))
    (display "=")
    (display (cdr x)))
   attrs)
  (newline)
  (set! level (1+ level)))
@end lisp

The handler for end tags is simpler: it must only decrease the level:

@lisp
(define (elt-end name)
  (set! level (1- level)))
@end lisp
  
Finally, create a parser and parse the input:

@lisp
(xml-parse (xml-make-parser #:start-element-handler elt-start
                            #:end-element-handler elt-end))
@end lisp

@node creating parsers
@section Creating XML Parsers
@cindex parsers, XML, creating
Gamma provides several functions for creating and modifying
@acronym{XML} parsers.  The @code{xml-primitive-make-parser} and
@code{xml-primitive-set-handler} are lower level interfaces, provided
for those who wish to further extend Gamma functionality. Higher level
interfaces are @code{xml-make-parser} and @code{xml-set-handler} which
we recommend for regular users.

@anchor{xml-primitive-make-parser}
@deffn {Scheme procedure} xml-primitive-make-parser enc sep
Return a new @acronym{XML} parser. If @var{enc} is given, it must be one of:
@samp{US-ASCII}, @samp{UTF-8}, @samp{UTF-16}, @samp{ISO-8859-1}.  If @var{sep}
is given, the returned parser has namespace processing in effect.  In
that case, @var{sep} is a character which is used as a separator
between the namespace @acronym{URI} and the local part of the name in
returned namespace element and attribute names.
@end deffn

@deffn {Scheme procedure} xml-set-encoding parser enc
Set the encoding to be used by the @var{parser}.  The latter must be a
value returned from a previous call to
@code{xml-primitive-make-parser} or @code{xml-make-parser}.

The sequence:

@lisp
@group
  (let ((parser (xml-primitive-make-parser)))
    (xml-set-encoding parser encoding)
    @dots{}
@end group    
@end lisp

@noindent
is equivalent to:

@lisp
  (let ((parser (xml-primitive-make-parser encoding)))
   @dots{}
@end lisp

@noindent
and to:

@lisp
  (let ((parser (xml-make-parser encoding)))
   @dots{}
@end lisp
@end deffn

@deffn {Scheme procedure} xml-primitive-set-handler parser key handler
Set @acronym{XML} handler for an event.  Arguments are:

@table @var
@item parser
A valid @acronym{XML} parser

@anchor{handler-keyword}
@item key
A key, identifying the event.  For example,
@samp{#:start-element-handler} sets handler which is called for start
tags.

@xref{handlers}, for its values and their meaning.

@item handler
Handler procedure.
@end table

@end deffn

@deffn {Scheme function} xml-set-handler parser args@dots{}
Sets several handlers at once.  Optional arguments (@var{args})
are constracted of keywords (as described in
@pxref{handler-keyword}), followed by their arguments, for example:

@lisp
(xml-set-handler parser
      #:start-element-handler elt-start
      #:end-element-handler elt-end)
@end lisp      
@end deffn

@deffn {Scheme function} xml-make-parser [enc [sep]] args@dots{}
Create a parser and set its handlers.  Optional @var{enc} and
@var{sep} have the same meaning as in @ref{xml-primitive-make-parser}.
The rest of arguments define handlers for the new parser.  They must
be supplied in pairs: a keyword (as described in
@pxref{handler-keyword}), followed by its argument.  For example:

@lisp
(xml-make-parser "US-ASCII"
      #:start-element-handler elt-start
      #:end-element-handler elt-end)
@end lisp

This call creates a new parser for documents in @samp{US-ASCII}
encoding and sets two handlers: for element start and for element end.
This call is equivalent to:

@lisp
(let ((p (xml-primitive-make-parser "US-ASCII")))
   (xml-primitive-set-handler p #:start-element-handler elt-start)
   (xml-primitive-set-handler p #:end-element-handler elt-end)
   @dots{}
@end lisp
@end deffn

@node parsing
@section Parser Functions

@deffn {Scheme procedure} xml-primitive-parse parser input isfinal
Parse next piece of input.  Arguments are:

@table @var
@item parser
A parser returned from a previous call to
@code{xml-primitive-make-parser} or @code{xml-make-parser}.

@item input
A piece of input text.

@item isfinal
Boolean value indicating whether @var{input} is the last part of
input.
@end table
@end deffn

@deffn {Scheme function} xml-parse-more parser input
Equivalent to:

@lisp
(xml-primitive-parse parser input #f)
@end lisp

@noindent
unless @var{input} is an end-of-file object, in which case it
is equivalent to:

@lisp
(xml-primitive-parse parser "" #t)
@end lisp
@end deffn

@deffn {Scheme function} xml-parse parser [port]
Reads @acronym{XML} input from @var{port} (or the standard input port,
if it is not given) and parses it using @code{xml-primitive-parse}.
@end deffn

@node errors
@section Error Handling
@cindex xml error handling
@cindex error handling, @acronym{XML}
When encountering an error. the @samp{gamma xml} functions use
Guile error reporting mechanism (@pxref{Error Reporting,
Procedures for Signaling Errors,,guile,The Guile Reference Manual}).
The @dfn{error key} indicates what type of error it was, and the
rest of arguments supply additional information about the error.
Recommended ways for handling errors in Guile are described in
@ref{Handling Errors, How to Handle Errors,,guile,The Guile Reference
Manual}). In this chapter we will describe how to handle errors
in @acronym{XML} input and other errors reported by the underlying
@file{libexpat} library.

@defvr {Error Key} gamma-xml-error
An error of this type is signalled when a of @samp{gamma xml}
functions encounters an @acronym{XML}-related error.
@end defvr

The arguments supplied with this error are:

@table @asis
@item key
The error key (@code{gamma-xml-error}).

@item func
Name of the function that generated the error.

@item fmt
Format string

@item fmt-args
Arguments for @samp{fmt}.

@item descr
Error description.  If there are no additional information, it is
@code{#f}.  Otherwise it is a list of 5 elements which describes the
error and its location in the input stream:

@enumerate 0
@item
Error code (number).

@item
Line number (starts at 1).

@item
Column number (starts at 0).

@item
Context in which the error occured, i.e. a part of the input text
which was found to contain the error.

@item
Offset of point that caused the error within the context.
@end enumerate
@end table

A special syntax is provided to extract parts of the @samp{descr}
list:

@deffn {Gamma Syntax} xml-error-descr descr key
Extract from @var{descr} the part identified by @var{key}.  Use
this macro in the error handlers.  Valid values for @var{key} are:

@defvr {xml-error-descr key} #:error-code
Return the error code.
@end defvr

@defvr {xml-error-descr key} #:line
Return line number.
@end defvr

@defvr {xml-error-descr key} #:column
Return column number.
@end defvr

@defvr {xml-error-descr key} #:has-context?
Return @code{#t} if the description has context part.  Use the two
keywords below only if

@lisp
(xml-error-descr d #:has-context?
@end lisp

@noindent
returned @code{#t}.
@end defvr

@defvr {xml-error-descr key} #:context
Return context string.
@end defvr

@defvr {xml-error-descr key} #:error-offset
Return the location within @code{#:context} where the error occurred.
@end defvr
@end deffn

If no special handler is set, the default @command{guile} error
handler displays the error and its approximate location on the
standard error port.  For example, given the following input file:

@example
@group
$ cat input.xml
<input>
 <ref a=1/>
</input>
@end group
@end example

@noindent
the @file{xmlck.scm} (@pxref{xmlck.scm}) produces:

@example
@group
$ guile -s examples/xmlck.scm < input.xml
ERROR: In procedure xml-primitive-parse:
ERROR: not well-formed (invalid token) near line 2
@end group
@end example

@anchor{catching gamma-xml-error}
To provide a more detailed diagnostics, catch the
@code{gamma-xml-error} code and use information from the @samp{descr}
list.  For example:

@lisp
(catch 'gamma-xml-error
       (lambda ()
	 (xml-parse (xml-make-parser)))
       (lambda (key func fmt args descr)
	 (with-output-to-port
	     (current-error-port)
	   (lambda ()
	     (cond
	      ((not descr)
	       (apply format #t fmt args)
	       (newline))
	      (else
	       (format #t
		       "~A:~A: ~A~%"
		       (xml-error-descr descr #:line)
		       (xml-error-descr descr #:column)
		       (xml-error-string (xml-error-descr descr #:error-code)))
	       (if (xml-error-descr descr #:has-context?)
		   (let ((ctx-text (xml-error-descr descr #:context))
			 (ctx-pos  (xml-error-descr descr #:error-offset)))
		     (format #t
			     "Context (^ marks the point): ~A^~A~%"
			     (substring ctx-text 0 ctx-pos)
			     (substring ctx-text ctx-pos))))
	       (exit 1)))))))
@end lisp

When applied to the same input document as in the previous example,
this code produces:

@example
@group
$ guile -s examples/xml-check.scm < input.xml
2:8: not well-formed (invalid token)
Context (^ marks the point): <input>
 <ref a=^1/>

@end group
@end example

@node handlers
@section Expat Handlers
@cindex handlers, expat
@cindex callbacks, expat
This section describes all available element handlers.  For clarity,
each handler is described in its own subsection.  For each handler, we
indicate a @dfn{keyword} that is used when registering this
handler and the @dfn{handler prototype}.

To register handlers, use @code{xml-make-parser} or
@code{xml-set-handler} functions.  @xref{creating parsers}, for a
detailed discussion of these functions.

@menu
* start-element-handler::
* end-element-handler::
* character-data-handler::
* processing-instruction-handler::
* comment-handler::
* start-cdata-section-handler::
* end-cdata-section-handler::
* default-handler::
* default-handler-expand::
* skipped-entity-handler::
* start-namespace-decl-handler::
* end-namespace-decl-handler::
* xml-decl-handler::
* start-doctype-decl-handler::
* end-doctype-decl-handler::
* attlist-decl-handler::
* entity-decl-handler::
* notation-decl-handler::
* not-standalone-handler::
@end menu

@node start-element-handler
@subsection start-element-handler
@cindex start element handler
@cindex handler, start element
@defvr {Handler Keyword} #:start-element-handler
Sets handler for start (and empty) tags. 
@end defvr

The hanlder must be defined as follows:

@deffn {Handler prototype} start-element name attrs
Arguments:

@table @var
@item name
Element name.

@item attrs
A list of element attributes.  Each attribute is represented by a cons
(@samp{car} holds attribute name, @samp{cdr} holds its value).
@end table
@end deffn

@node end-element-handler
@subsection end-element-handler
@cindex end element handler
@cindex handler, end element
@defvr {Handler Keyword} #:end-element-handler
Sets handler for end (and empty) tags.  An empty tag generates a call
to both start and end handlers (in that order).
@end defvr

The hanlder must be defined as follows:

@deffn {Handler prototype} end-element name
Arguments:

@table @var
@item name
Element name
@end table
@end deffn

@node character-data-handler
@subsection character-data-handler
@cindex character data handler
@cindex handler, character data
@defvr {Handler Keyword} #:character-data-handler
Sets a text handler. A single block of contiguous text free of markup
may result in a sequence of calls to this handler. So, if you are
searching for a pattern in the text, it may be split across calls to
this handler.
@end defvr

The handler itself is defined as:

@deffn {Handler prototype} character-data text
Arguments:

@table @var
@item text
The text.
@end table
@end deffn

@node processing-instruction-handler
@subsection processing-instruction-handler
@cindex processing instruction handler
@cindex handler, processing instruction

@defvr {Handler Keyword} #:processing-instruction-handler
Set a handler for @dfn{processing instructions}.
@end defvr

@deffn {Handler prototype} processing-instruction target data
Arguments are:

@table @var
@item target
First word in the processing instruction.

@item data
The rest of the characters in the processing instruction, after
@var{target} and whitespace following it.
@end table
@end deffn

@node comment-handler
@subsection comment-handler

@defvr {Handler Keyword} #:comment-handler
Sets a handler for comments.
@end defvr

@deffn {Handler prototype} comment text
@table @var
@item text
The text inside the comment delimiters.
@end table
@end deffn

@node start-cdata-section-handler
@subsection start-cdata-section-handler
@cindex start cdata section handler
@cindex handler, start cdata section

@defvr {Handler Keyword} #:start-cdata-section-handler
Sets a handler that gets called at the beginning of a CDATA section.
@end defvr

The handler is defined as follows:

@deffn {Handler prototype} start-cdata-section
@end deffn

@node end-cdata-section-handler
@subsection end-cdata-section-handler
@cindex end cdata section handler
@cindex handler, end cdata section

@defvr {Handler Keyword} #:end-cdata-section-handler
Sets a handler that gets called at the end of a CDATA section.
@end defvr

The handler is defined as:

@deffn {Handler prototype} end-cdata-section
@end deffn

@node default-handler
@subsection default-handler
@cindex default handler
@cindex handler, default

@defvr {Handler Keyword} #:default-handler
Sets a handler for any characters in the document which wouldn't
otherwise be handled.  This includes both data for which no handlers
can be set (like some kinds of @acronym{DTD} declarations) and data
which could be reported but which currently has no handler set. 
@end defvr

@deffn {Handler prototype} default text
@table @var
@item text
A string containing all non-handled characters, which are passed
exactly as they were present in the input @acronym{XML} document
except that they will be encoded in UTF-8 or UTF-16.  Line boundaries
are not normalized.  Note that a byte order mark character is not
passed to the default handler.  There are no guarantees about how
characters are divided between calls to the default handler: for
example, a comment might be split between multiple calls.  Setting the
@samp{default} handler has the side effect of turning off expansion of
references to internally defined general entities.  Such references
are passed to the default handler verbatim.
@end table
@end deffn

@node default-handler-expand
@subsection default-handler-expand
@cindex default handler, with expansion
@cindex handler, default, with expansion

@defvr {Handler Keyword} #:default-handler-expand
This sets a default handler as above, but does not inhibit the
expansion of internal entity references.  Any entity references are not
passed to the handler.
@end defvr

The handler prototype is the same as in @ref{default-handler}.

@node skipped-entity-handler
@subsection skipped-entity-handler
@cindex skipped entity handler
@cindex handler, skipped entity

@defvr {Handler Keyword} #:skipped-entity-handler
Set a skipped entity handler, i.e. a handler which is called if:

@itemize @bullet
@item An entity reference is encountered for which no declaration has
been read and this is not an error.
@item An internal entity reference is read, but not expanded, because
a @samp{#:default-handler} has been set.
@end itemize
@end defvr

@deffn {Handler prototype} skipped-entity entity-name parameter?
Arguments are:

@table @var
@item entity-name
Name of the entity.

@item parameter?
This argument is @code{#t} if the entity is a parameter, and @code{#f}
otherwise.
@end table
@end deffn

@node start-namespace-decl-handler
@subsection start-namespace-decl-handler
@cindex start namespace declaration handler
@cindex handler, start namespace declaration

@defvr {Handler Keyword} #:start-namespace-decl-handler
Set a handler to be called when a namespace is declared.
@end defvr

@deffn {Handler prototype} start-namespace-decl prefix uri
Arguments:

@table @var
@item prefix
Namespace prefix.

@item uri
Namespace @acronym{URI}.
@end table
@end deffn

@node end-namespace-decl-handler
@subsection end-namespace-decl-handler
@cindex end namespace declaration handler
@cindex handler, end namespace declaration

@defvr {Handler Keyword} #:end-namespace-decl-handler
Set a handler to be called when leaving the scope of a namespace
declaration.  This will be called, for each namespace declaration,
after the handler for the end tag of the element in which the
namespace was declared.
@end defvr

The handler prototype is:

@deffn {Handler prototype} end-namespace-decl prefix
@end deffn

@node xml-decl-handler
@subsection xml-decl-handler
@cindex @acronym{XML} declaration handler
@cindex handler, @acronym{XML} declaration

@defvr {Handler Keyword} #:xml-decl-handler
Sets a handler that is called for @acronym{XML} declarations and also
for text declarations discovered in external entities.
@end defvr

@deffn {Handler prototype} xml-decl version encoding . detail
Arguments:

@table @var
@item version
Version specification (string), or @code{#f}, for text declarations.

@item encoding
Encoding.  May be @code{#f}.

@item detail
@samp{Unspecified}, if there was no standalone parameter in the
declaration.  Otherwise, @code{#t} or @code{#f} depending on whether
it was given as @samp{yes} or @samp{no}. 
@end table
@end deffn

@node start-doctype-decl-handler
@subsection start-doctype-decl-handler
@cindex start doctype declaration handler
@cindex handler, start doctype declaration

@defvr {Handler Keyword} #:start-doctype-decl-handler
Set a handler that is called at the start of a @samp{DOCTYPE} declaration,
before any external or internal subset is parsed.
@end defvr

@deffn {Handler prototype} start-doctype-decl name sysid pubid @
 has-internal-subset?
Arguments:

@table @var
@item name
Declaration name.

@item sysid
System @acronym{ID}.  May be @code{#f}.

@item pubid
Public @acronym{ID}.  May be @code{#f}.

@item has-internal-subset?
@code{#t} if the @samp{DOCTYPE} declaration has an internal subset,
@code{#f} otherwise.
@end table
@end deffn

@node end-doctype-decl-handler
@subsection end-doctype-decl-handler
@cindex end doctype declaration handler
@cindex handler, end doctype declaration

@defvr {Handler Keyword} #:end-doctype-decl-handler
Set a handler that is called at the end of a @samp{DOCTYPE}
declaration, after parsing any external subset.
@end defvr

The handler takes no arguments:

@deffn {Handler prototype} end-doctype-decl
@end deffn

@node attlist-decl-handler
@subsection attlist-decl-handler
@cindex attlist declaration handler
@cindex handler, attlist declaration

@defvr {Handler Keyword} #:attlist-decl-handler
Sets a handler for @samp{attlist} declarations in the
@acronym{DTD}.  This handler is called for each attribute, which
means, in particular, that a single attlist declaration with multiple
attributes causes multiple calls to this handler.
@end defvr

The handler prototype is:

@deffn {Handler prototype} attlist-decl el-name att-name att-type detail
Argument:

@table @var
@item el-name
Name of the element for which the attribute is being declared.

@item att-name
Attribute name.

@item detail
Default value, if @var{el-name} is a @samp{#FIXED} attribute,
@code{#t}, if it is a @samp{#REQUIRED} attribute, and @code{#f}, if it
is a @samp{#IMPLIED} attribute.
@end table
@end deffn

@node entity-decl-handler
@subsection entity-decl-handler
@cindex entity declaration handler
@cindex handler, entity declaration

@defvr {Handler Keyword} #:entity-decl-handler
Sets a handler that will be called for all entity declarations.
@end defvr


@deffn {Handler prototype} entity-decl name param? value base sys-id pub-id @
 notation
Arguments:

@table @var
@item name
Entity name.

@item param?
For parameter entities, @code{#t}.  Otherwise, @code{#f}.

@item value
For internal entities, entity value.  Otherwise, @code{#f}.

@item base
Base.

@item sys-id
System @acronym{ID}.  For internal entities -- @code{#f}.

@item pub-id
Public @acronym{ID}.  For internal entities -- @code{#f}.

@item notation
Notation name, for unparsed entity declarations.  Otherwise,
@code{#f}.  Unparsed are entity declarations that have a notation
(@samp{NDATA}) field, such as: 

@example
<!ENTITY logo SYSTEM "images/logo.gif" NDATA gif>
@end example

@end table
@end deffn

@node notation-decl-handler
@subsection notation-decl-handler
@cindex notation declaration handler
@cindex handler, notation declaration

@defvr {Handler Keyword} #:notation-decl-handler
Sets a handler that receives notation declarations.
@end defvr

Handler prototype is:

@deffn {Handler prototype} notation-decl notation-name base @
 system-id public-id
@end deffn

@node not-standalone-handler
@subsection not-standalone-handler
@cindex not standalone document handler
@cindex handler, not standalone document

@defvr {Handler Keyword} #:not-standalone-handler
Sets a handler that is called if the document is not @dfn{standalone}, i.e.
when there is an external subset or a reference to a parameter entity,
but does not have @samp{standalone} set to "yes" in an @acronym{XML}
declaration.
@end defvr

The handler takes no arguments:

@deffn {Handler prototype} not-standalone 
@end deffn

@node miscellaneous functions
@section miscellaneous functions

@deffn {Scheme function} xml-expat-version-string
Return the version of the expat library as a string.

For example:

@lisp
(xml-expat-version-string) @result{} "expat_2.0.1"
@end lisp
@end deffn

@deffn {Scheme function} xml-expat-version
Return the version of the expat library as a triplet: @samp{(major
minor micro)}.

For example:
@lisp
(xml-expat-version) @result{} (2 0 1)
@end lisp
@end deffn

@deffn {Scheme function} xml-default-current
Pass current markup to the default handler (@pxref{default-handler}).
This function may be called only from a callback handler.
@end deffn

@deffn {Scheme function} xml-error-string code)
Return a textual description corresponding to the @var{code} argument.
@xref{catching gamma-xml-error}, for an example of using this
function.
@end deffn

@deffn {Scheme function} xml-current-line-number parser
Return number of the current input line in @var{parser}.  Input lines
are numbered from @samp{1}.
@end deffn

@deffn {Scheme function} xml-current-column-number parser
Return number of column in the current input line.
@end deffn

@deffn {Scheme function} xml-current-byte-count parser
Return the number of bytes in the current event.  Returns @samp{0} if
the event is inside a reference to an internal entity and for the
end-tag event for empty element tags (the later can be used to
distinguish empty-element tags from empty elements using separate
start and end tags).  
@end deffn

Return to:

Send suggestions and report system problems to the System administrator.