]> matita.cs.unibo.it Git - helm.git/blob - helm/DEVEL/pxp/pxp/doc/manual/html/x1629.html
- the mathql interpreter is not helm-dependent any more
[helm.git] / helm / DEVEL / pxp / pxp / doc / manual / html / x1629.html
1 <HTML
2 ><HEAD
3 ><TITLE
4 >Resolvers and sources</TITLE
5 ><META
6 NAME="GENERATOR"
7 CONTENT="Modular DocBook HTML Stylesheet Version 1.46"><LINK
8 REL="HOME"
9 TITLE="The PXP user's guide"
10 HREF="index.html"><LINK
11 REL="UP"
12 TITLE="Configuring and calling the parser"
13 HREF="c1567.html"><LINK
14 REL="PREVIOUS"
15 TITLE="Configuring and calling the parser"
16 HREF="c1567.html"><LINK
17 REL="NEXT"
18 TITLE="The DTD classes"
19 HREF="x1812.html"><LINK
20 REL="STYLESHEET"
21 TYPE="text/css"
22 HREF="markup.css"></HEAD
23 ><BODY
24 CLASS="SECT1"
25 BGCOLOR="#FFFFFF"
26 TEXT="#000000"
27 LINK="#0000FF"
28 VLINK="#840084"
29 ALINK="#0000FF"
30 ><DIV
31 CLASS="NAVHEADER"
32 ><TABLE
33 WIDTH="100%"
34 BORDER="0"
35 CELLPADDING="0"
36 CELLSPACING="0"
37 ><TR
38 ><TH
39 COLSPAN="3"
40 ALIGN="center"
41 >The PXP user's guide</TH
42 ></TR
43 ><TR
44 ><TD
45 WIDTH="10%"
46 ALIGN="left"
47 VALIGN="bottom"
48 ><A
49 HREF="c1567.html"
50 >Prev</A
51 ></TD
52 ><TD
53 WIDTH="80%"
54 ALIGN="center"
55 VALIGN="bottom"
56 >Chapter 4. Configuring and calling the parser</TD
57 ><TD
58 WIDTH="10%"
59 ALIGN="right"
60 VALIGN="bottom"
61 ><A
62 HREF="x1812.html"
63 >Next</A
64 ></TD
65 ></TR
66 ></TABLE
67 ><HR
68 ALIGN="LEFT"
69 WIDTH="100%"></DIV
70 ><DIV
71 CLASS="SECT1"
72 ><H1
73 CLASS="SECT1"
74 ><A
75 NAME="AEN1629"
76 >4.2. Resolvers and sources</A
77 ></H1
78 ><DIV
79 CLASS="SECT2"
80 ><H2
81 CLASS="SECT2"
82 ><A
83 NAME="AEN1631"
84 >4.2.1. Using the built-in resolvers (called sources)</A
85 ></H2
86 ><P
87 >The type <TT
88 CLASS="LITERAL"
89 >source</TT
90 > enumerates the two
91 possibilities where the document to parse comes from.
92
93 <PRE
94 CLASS="PROGRAMLISTING"
95 >type source =
96     Entity of ((dtd -&gt; Pxp_entity.entity) * Pxp_reader.resolver)
97   | ExtID of (ext_id * Pxp_reader.resolver)</PRE
98 >
99
100 You normally need not to worry about this type as there are convenience
101 functions that create <TT
102 CLASS="LITERAL"
103 >source</TT
104 > values:
105
106
107             <P
108 ></P
109 ><UL
110 COMPACT="COMPACT"
111 ><LI
112 STYLE="list-style-type: disc"
113 ><P
114 ><TT
115 CLASS="LITERAL"
116 >from_file s</TT
117 >: The document is read from
118 file <TT
119 CLASS="LITERAL"
120 >s</TT
121 >; you may specify absolute or relative path names.
122 The file name must be encoded as UTF-8 string.</P
123 ><P
124 >There is an optional argument <TT
125 CLASS="LITERAL"
126 >~system_encoding</TT
127 >
128 specifying the character encoding which is used for the names of the file
129 system. For example, if this encoding is ISO-8859-1 and <TT
130 CLASS="LITERAL"
131 >s</TT
132 > is
133 also a ISO-8859-1 string, you can form the source:
134
135 <PRE
136 CLASS="PROGRAMLISTING"
137 >let s_utf8  =  recode_string ~in_enc:`Enc_iso88591 ~out_enc:`Enc_utf8 s in
138 from_file ~system_encoding:`Enc_iso88591 s_utf8</PRE
139 ></P
140 ><P
141 >This <TT
142 CLASS="LITERAL"
143 >source</TT
144 > has the advantage that
145 it is able to resolve inner external entities; i.e. if your document includes
146 data from another file (using the <TT
147 CLASS="LITERAL"
148 >SYSTEM</TT
149 > attribute), this
150 mode will find that file. However, this mode cannot resolve
151 <TT
152 CLASS="LITERAL"
153 >PUBLIC</TT
154 > identifiers nor <TT
155 CLASS="LITERAL"
156 >SYSTEM</TT
157 > identifiers
158 other than "file:".</P
159 ></LI
160 ><LI
161 STYLE="list-style-type: disc"
162 ><P
163 ><TT
164 CLASS="LITERAL"
165 >from_channel ch</TT
166 >: The document is read
167 from the channel <TT
168 CLASS="LITERAL"
169 >ch</TT
170 >. In general, this source also supports
171 file URLs found in the document; however, by default only absolute URLs are
172 understood. It is possible to associate an ID with the channel such that the
173 resolver knows how to interpret relative URLs:
174
175 <PRE
176 CLASS="PROGRAMLISTING"
177 >from_channel ~id:(System "file:///dir/dir1/") ch</PRE
178 >
179
180 There is also the ~system_encoding argument specifying how file names are
181 encoded. - The example from above can also be written (but it is no
182 longer possible to interpret relative URLs because there is no ~id argument,
183 and computing this argument is relatively complicated because it must
184 be a valid URL):
185
186 <PRE
187 CLASS="PROGRAMLISTING"
188 >let ch = open_in s in
189 let src = from_channel ~system_encoding:`Enc_iso88591 ch in
190 ...;
191 close_in ch</PRE
192 ></P
193 ></LI
194 ><LI
195 STYLE="list-style-type: disc"
196 ><P
197 ><TT
198 CLASS="LITERAL"
199 >from_string s</TT
200 >: The string
201 <TT
202 CLASS="LITERAL"
203 >s</TT
204 > is the document to parse. This mode is not able to
205 interpret file names of <TT
206 CLASS="LITERAL"
207 >SYSTEM</TT
208 > clauses, nor it can look up
209 <TT
210 CLASS="LITERAL"
211 >PUBLIC</TT
212 > identifiers. </P
213 ><P
214 >Normally, the encoding of the string is detected as usual
215 by analyzing the XML declaration, if any. However, it is also possible to
216 specify the encoding directly:
217
218 <PRE
219 CLASS="PROGRAMLISTING"
220 >let src = from_string ~fixenc:`ISO-8859-2 s</PRE
221 ></P
222 ></LI
223 ><LI
224 STYLE="list-style-type: disc"
225 ><P
226 ><TT
227 CLASS="LITERAL"
228 >ExtID (id, r)</TT
229 >: The document to parse
230 is denoted by the identifier <TT
231 CLASS="LITERAL"
232 >id</TT
233 > (either a
234 <TT
235 CLASS="LITERAL"
236 >SYSTEM</TT
237 > or <TT
238 CLASS="LITERAL"
239 >PUBLIC</TT
240 > clause), and this
241 identifier is interpreted by the resolver <TT
242 CLASS="LITERAL"
243 >r</TT
244 >. Use this mode
245 if you have written your own resolver.</P
246 ><P
247 >Which character sets are possible depends on the passed
248 resolver <TT
249 CLASS="LITERAL"
250 >r</TT
251 >.</P
252 ></LI
253 ><LI
254 STYLE="list-style-type: disc"
255 ><P
256 ><TT
257 CLASS="LITERAL"
258 >Entity (get_entity, r)</TT
259 >: The document
260 to parse is returned by the function invocation <TT
261 CLASS="LITERAL"
262 >get_entity
263 dtd</TT
264 >, where <TT
265 CLASS="LITERAL"
266 >dtd</TT
267 > is the DTD object to use (it may be
268 empty). Inner external references occuring in this entity are resolved using
269 the resolver <TT
270 CLASS="LITERAL"
271 >r</TT
272 >.</P
273 ><P
274 >Which character sets are possible depends on the passed
275 resolver <TT
276 CLASS="LITERAL"
277 >r</TT
278 >.</P
279 ></LI
280 ></UL
281 ></P
282 ></DIV
283 ><DIV
284 CLASS="SECT2"
285 ><H2
286 CLASS="SECT2"
287 ><A
288 NAME="AEN1682"
289 >4.2.2. The resolver API</A
290 ></H2
291 ><P
292 >A resolver is an object that can be opened like a file, but you
293 do not pass the file name to the resolver, but the XML identifier of the entity
294 to read from (either a <TT
295 CLASS="LITERAL"
296 >SYSTEM</TT
297 > or <TT
298 CLASS="LITERAL"
299 >PUBLIC</TT
300 >
301 clause). When opened, the resolver must return the
302 <TT
303 CLASS="LITERAL"
304 >Lexing.lexbuf</TT
305 > that reads the characters.  The resolver can
306 be closed, and it can be cloned. Furthermore, it is possible to tell the
307 resolver which character set it should assume. - The following from Pxp_reader:
308
309 <PRE
310 CLASS="PROGRAMLISTING"
311 >exception Not_competent
312 exception Not_resolvable of exn
313
314 class type resolver =
315   object
316     method init_rep_encoding : rep_encoding -&#62; unit
317     method init_warner : collect_warnings -&#62; unit
318     method rep_encoding : rep_encoding
319     method open_in : ext_id -&#62; Lexing.lexbuf
320     method close_in : unit
321     method change_encoding : string -&#62; unit
322     method clone : resolver
323     method close_all : unit
324   end</PRE
325 >
326
327 The resolver object must work as follows:</P
328 ><P
329 >            <P
330 ></P
331 ><UL
332 COMPACT="COMPACT"
333 ><LI
334 STYLE="list-style-type: disc"
335 ><P
336 >When the parser is called, it tells the resolver the
337 warner object and the internal encoding by invoking
338 <TT
339 CLASS="LITERAL"
340 >init_warner</TT
341 > and <TT
342 CLASS="LITERAL"
343 >init_rep_encoding</TT
344 >. The
345 resolver should store these values. The method <TT
346 CLASS="LITERAL"
347 >rep_encoding</TT
348 >
349 should return the internal encoding.</P
350 ></LI
351 ><LI
352 STYLE="list-style-type: disc"
353 ><P
354 >If the parser wants to read from the resolver, it invokes
355 the method <TT
356 CLASS="LITERAL"
357 >open_in</TT
358 >. Either the resolver succeeds, in which
359 case the <TT
360 CLASS="LITERAL"
361 >Lexing.lexbuf</TT
362 > reading from the file or stream must
363 be returned, or opening fails. In the latter case the method implementation
364 should raise an exception (see below).</P
365 ></LI
366 ><LI
367 STYLE="list-style-type: disc"
368 ><P
369 >If the parser finishes reading, it calls the
370 <TT
371 CLASS="LITERAL"
372 >close_in</TT
373 > method.</P
374 ></LI
375 ><LI
376 STYLE="list-style-type: disc"
377 ><P
378 >If the parser finds a reference to another external
379 entity in the input stream, it calls <TT
380 CLASS="LITERAL"
381 >clone</TT
382 > to get a second
383 resolver which must be initially closed (not yet connected with an input
384 stream).  The parser then invokes <TT
385 CLASS="LITERAL"
386 >open_in</TT
387 > and the other
388 methods as described.</P
389 ></LI
390 ><LI
391 STYLE="list-style-type: disc"
392 ><P
393 >If you already know the character set of the input
394 stream, you should recode it to the internal encoding, and define the method
395 <TT
396 CLASS="LITERAL"
397 >change_encoding</TT
398 > as an empty method.</P
399 ></LI
400 ><LI
401 STYLE="list-style-type: disc"
402 ><P
403 >If you want to support multiple external character sets,
404 the object must follow a much more complicated protocol. Directly after
405 <TT
406 CLASS="LITERAL"
407 >open_in</TT
408 > has been called, the resolver must return a lexical
409 buffer that only reads one byte at a time. This is only possible if you create
410 the lexical buffer with <TT
411 CLASS="LITERAL"
412 >Lexing.from_function</TT
413 >; the function
414 must then always return 1 if the EOF is not yet reached, and 0 if EOF is
415 reached. If the parser has read the first line of the document, it will invoke
416 <TT
417 CLASS="LITERAL"
418 >change_encoding</TT
419 > to tell the resolver which character set to
420 assume. From this moment, the object can return more than one byte at once. The
421 argument of <TT
422 CLASS="LITERAL"
423 >change_encoding</TT
424 > is either the parameter of the
425 "encoding" attribute of the XML declaration, or the empty string if there is
426 not any XML declaration or if the declaration does not contain an encoding
427 attribute. </P
428 ><P
429 >At the beginning the resolver must only return one
430 character every time something is read from the lexical buffer. The reason for
431 this is that you otherwise would not exactly know at which position in the
432 input stream the character set changes.</P
433 ><P
434 >If you want automatic recognition of the character set,
435 it is up to the resolver object to implement this.</P
436 ></LI
437 ><LI
438 STYLE="list-style-type: disc"
439 ><P
440 >If an error occurs, the parser calls the method
441 <TT
442 CLASS="LITERAL"
443 >close_all</TT
444 > for the top-level resolver; this method should
445 close itself (if not already done) and all clones.</P
446 ></LI
447 ></UL
448 ></P
449 ><DIV
450 CLASS="FORMALPARA"
451 ><P
452 ><B
453 >Exceptions. </B
454 >It is possible to chain resolvers such that when the first resolver is not able
455 to open the entity, the other resolvers of the chain are tried in turn. The
456 method <TT
457 CLASS="LITERAL"
458 >open_in</TT
459 > should raise the exception
460 <TT
461 CLASS="LITERAL"
462 >Not_competent</TT
463 > to indicate that the next resolver should try
464 to open the entity. If the resolver is able to handle the ID, but some other
465 error occurs, the exception <TT
466 CLASS="LITERAL"
467 >Not_resolvable</TT
468 > should be raised
469 to force that the chain breaks.
470           </P
471 ></DIV
472 ><P
473 >Example: How to define a resolver that is equivalent to
474 from_string: ...</P
475 ></DIV
476 ><DIV
477 CLASS="SECT2"
478 ><H2
479 CLASS="SECT2"
480 ><A
481 NAME="AEN1728"
482 >4.2.3. Predefined resolver components</A
483 ></H2
484 ><P
485 >There are some classes in Pxp_reader that define common resolver behaviour.
486
487 <PRE
488 CLASS="PROGRAMLISTING"
489 >class resolve_read_this_channel : 
490     ?id:ext_id -&#62; 
491     ?fixenc:encoding -&#62; 
492     ?auto_close:bool -&#62; 
493     in_channel -&#62; 
494         resolver</PRE
495 >
496
497 Reads from the passed channel (it may be even a pipe). If the
498 <TT
499 CLASS="LITERAL"
500 >~id</TT
501 > argument is passed to the object, the created resolver
502 accepts only this ID. Otherwise all IDs are accepted.  - Once the resolver has
503 been cloned, it does not accept any ID. This means that this resolver cannot
504 handle inner references to external entities. Note that you can combine this
505 resolver with another resolver that can handle inner references (such as
506 resolve_as_file); see class 'combine' below.  - If you pass the
507 <TT
508 CLASS="LITERAL"
509 >~fixenc</TT
510 > argument, the encoding of the channel is set to the
511 passed value, regardless of any auto-recognition or any XML declaration. - If
512 <TT
513 CLASS="LITERAL"
514 >~auto_close = true</TT
515 > (which is the default), the channel is
516 closed after use. If <TT
517 CLASS="LITERAL"
518 >~auto_close = false</TT
519 >, the channel is
520 left open.
521  </P
522 ><P
523 ><PRE
524 CLASS="PROGRAMLISTING"
525 >class resolve_read_any_channel : 
526     ?auto_close:bool -&#62; 
527     channel_of_id:(ext_id -&#62; (in_channel * encoding option)) -&#62; 
528         resolver</PRE
529 >
530
531 This resolver calls the function <TT
532 CLASS="LITERAL"
533 >~channel_of_id</TT
534 > to open a
535 new channel for the passed <TT
536 CLASS="LITERAL"
537 >ext_id</TT
538 >. This function must either
539 return the channel and the encoding, or it must fail with Not_competent.  The
540 function must return <TT
541 CLASS="LITERAL"
542 >None</TT
543 > as encoding if the default
544 mechanism to recognize the encoding should be used. It must return
545 <TT
546 CLASS="LITERAL"
547 >Some e</TT
548 > if it is already known that the encoding of the
549 channel is <TT
550 CLASS="LITERAL"
551 >e</TT
552 >.  If <TT
553 CLASS="LITERAL"
554 >~auto_close = true</TT
555 >
556 (which is the default), the channel is closed after use. If
557 <TT
558 CLASS="LITERAL"
559 >~auto_close = false</TT
560 >, the channel is left open.</P
561 ><P
562 ><PRE
563 CLASS="PROGRAMLISTING"
564 >class resolve_read_url_channel :
565     ?base_url:Neturl.url -&#62;
566     ?auto_close:bool -&#62; 
567     url_of_id:(ext_id -&#62; Neturl.url) -&#62; 
568     channel_of_url:(Neturl.url -&#62; (in_channel * encoding option)) -&#62; 
569         resolver</PRE
570 >
571
572 When this resolver gets an ID to read from, it calls the function
573 <TT
574 CLASS="LITERAL"
575 >~url_of_id</TT
576 > to get the corresponding URL. This URL may be a
577 relative URL; however, a URL scheme must be used which contains a path.  The
578 resolver converts the URL to an absolute URL if necessary.  The second
579 function, <TT
580 CLASS="LITERAL"
581 >~channel_of_url</TT
582 >, is fed with the absolute URL as
583 input. This function opens the resource to read from, and returns the channel
584 and the encoding of the resource.</P
585 ><P
586 >Both functions, <TT
587 CLASS="LITERAL"
588 >~url_of_id</TT
589 > and
590 <TT
591 CLASS="LITERAL"
592 >~channel_of_url</TT
593 >, can raise Not_competent to indicate that
594 the object is not able to read from the specified resource. However, there is a
595 difference: A Not_competent from <TT
596 CLASS="LITERAL"
597 >~url_of_id</TT
598 > is left as it
599 is, but a Not_competent from <TT
600 CLASS="LITERAL"
601 >~channel_of_url</TT
602 > is converted to
603 Not_resolvable. So only <TT
604 CLASS="LITERAL"
605 >~url_of_id</TT
606 > decides which URLs are
607 accepted by the resolver and which not.</P
608 ><P
609 >The function <TT
610 CLASS="LITERAL"
611 >~channel_of_url</TT
612 > must return
613 <TT
614 CLASS="LITERAL"
615 >None</TT
616 > as encoding if the default mechanism to recognize the
617 encoding should be used. It must return <TT
618 CLASS="LITERAL"
619 >Some e</TT
620 > if it is
621 already known that the encoding of the channel is <TT
622 CLASS="LITERAL"
623 >e</TT
624 >.</P
625 ><P
626 >If <TT
627 CLASS="LITERAL"
628 >~auto_close = true</TT
629 > (which is the default), the channel is
630 closed after use. If <TT
631 CLASS="LITERAL"
632 >~auto_close = false</TT
633 >, the channel is
634 left open.</P
635 ><P
636 >Objects of this class contain a base URL relative to which relative URLs are
637 interpreted. When creating a new object, you can specify the base URL by
638 passing it as <TT
639 CLASS="LITERAL"
640 >~base_url</TT
641 > argument. When an existing object is
642 cloned, the base URL of the clone is the URL of the original object. - Note
643 that the term "base URL" has a strict definition in RFC 1808.</P
644 ><P
645 ><PRE
646 CLASS="PROGRAMLISTING"
647 >class resolve_read_this_string : 
648     ?id:ext_id -&#62; 
649     ?fixenc:encoding -&#62; 
650     string -&#62; 
651         resolver</PRE
652 >
653
654 Reads from the passed string. If the <TT
655 CLASS="LITERAL"
656 >~id</TT
657 > argument is passed
658 to the object, the created resolver accepts only this ID. Otherwise all IDs are
659 accepted. - Once the resolver has been cloned, it does not accept any ID. This
660 means that this resolver cannot handle inner references to external
661 entities. Note that you can combine this resolver with another resolver that
662 can handle inner references (such as resolve_as_file); see class 'combine'
663 below. - If you pass the <TT
664 CLASS="LITERAL"
665 >~fixenc</TT
666 > argument, the encoding of
667 the string is set to the passed value, regardless of any auto-recognition or
668 any XML declaration.</P
669 ><P
670 ><PRE
671 CLASS="PROGRAMLISTING"
672 >class resolve_read_any_string : 
673     string_of_id:(ext_id -&#62; (string * encoding option)) -&#62; 
674         resolver</PRE
675 >
676
677 This resolver calls the function <TT
678 CLASS="LITERAL"
679 >~string_of_id</TT
680 > to get the
681 string for the passed <TT
682 CLASS="LITERAL"
683 >ext_id</TT
684 >. This function must either
685 return the string and the encoding, or it must fail with Not_competent.  The
686 function must return <TT
687 CLASS="LITERAL"
688 >None</TT
689 > as encoding if the default
690 mechanism to recognize the encoding should be used. It must return
691 <TT
692 CLASS="LITERAL"
693 >Some e</TT
694 > if it is already known that the encoding of the
695 string is <TT
696 CLASS="LITERAL"
697 >e</TT
698 >.</P
699 ><P
700 ><PRE
701 CLASS="PROGRAMLISTING"
702 >class resolve_as_file :
703     ?file_prefix:[ `Not_recognized | `Allowed | `Required ] -&#62;
704     ?host_prefix:[ `Not_recognized | `Allowed | `Required ] -&#62;
705     ?system_encoding:encoding -&#62;
706     ?url_of_id:(ext_id -&#62; Neturl.url) -&#62; 
707     ?channel_of_url: (Neturl.url -&#62; (in_channel * encoding option)) -&#62;
708     unit -&#62; 
709         resolver</PRE
710 >
711 Reads from the local file system. Every file name is interpreted as
712 file name of the local file system, and the referred file is read.</P
713 ><P
714 >The full form of a file URL is: file://host/path, where
715 'host' specifies the host system where the file identified 'path'
716 resides. host = "" or host = "localhost" are accepted; other values
717 will raise Not_competent. The standard for file URLs is 
718 defined in RFC 1738.</P
719 ><P
720 >Option <TT
721 CLASS="LITERAL"
722 >~file_prefix</TT
723 >: Specifies how the "file:" prefix of
724 file names is handled:
725             <P
726 ></P
727 ><UL
728 COMPACT="COMPACT"
729 ><LI
730 STYLE="list-style-type: disc"
731 ><P
732 ><TT
733 CLASS="LITERAL"
734 >`Not_recognized:</TT
735 >The prefix is not
736 recognized.</P
737 ></LI
738 ><LI
739 STYLE="list-style-type: disc"
740 ><P
741 ><TT
742 CLASS="LITERAL"
743 >`Allowed:</TT
744 > The prefix is allowed but
745 not required (the default).</P
746 ></LI
747 ><LI
748 STYLE="list-style-type: disc"
749 ><P
750 ><TT
751 CLASS="LITERAL"
752 >`Required:</TT
753 > The prefix is
754 required.</P
755 ></LI
756 ></UL
757 ></P
758 ><P
759 >Option <TT
760 CLASS="LITERAL"
761 >~host_prefix:</TT
762 > Specifies how the "//host" phrase of
763 file names is handled:
764             <P
765 ></P
766 ><UL
767 COMPACT="COMPACT"
768 ><LI
769 STYLE="list-style-type: disc"
770 ><P
771 ><TT
772 CLASS="LITERAL"
773 >`Not_recognized:</TT
774 >The prefix is not
775 recognized.</P
776 ></LI
777 ><LI
778 STYLE="list-style-type: disc"
779 ><P
780 ><TT
781 CLASS="LITERAL"
782 >`Allowed:</TT
783 > The prefix is allowed but
784 not required (the default).</P
785 ></LI
786 ><LI
787 STYLE="list-style-type: disc"
788 ><P
789 ><TT
790 CLASS="LITERAL"
791 >`Required:</TT
792 > The prefix is
793 required.</P
794 ></LI
795 ></UL
796 ></P
797 ><P
798 >Option <TT
799 CLASS="LITERAL"
800 >~system_encoding:</TT
801 > Specifies the encoding of file
802 names of the local file system. Default: UTF-8.</P
803 ><P
804 >Options <TT
805 CLASS="LITERAL"
806 >~url_of_id</TT
807 >, <TT
808 CLASS="LITERAL"
809 >~channel_of_url</TT
810 >: Not
811 for the casual user!</P
812 ><P
813 ><PRE
814 CLASS="PROGRAMLISTING"
815 >class combine : 
816     ?prefer:resolver -&#62; 
817     resolver list -&#62; 
818         resolver</PRE
819 >
820
821 Combines several resolver objects. If a concrete entity with an
822 <TT
823 CLASS="LITERAL"
824 >ext_id</TT
825 > is to be opened, the combined resolver tries the
826 contained resolvers in turn until a resolver accepts opening the entity
827 (i.e. it does not raise Not_competent on open_in).</P
828 ><P
829 >Clones: If the 'clone' method is invoked before 'open_in', all contained
830 resolvers are cloned separately and again combined. If the 'clone' method is 
831 invoked after 'open_in' (i.e. while the resolver is open), additionally the
832 clone of the active resolver is flagged as being preferred, i.e. it is tried
833 first. </P
834 ></DIV
835 ></DIV
836 ><DIV
837 CLASS="NAVFOOTER"
838 ><HR
839 ALIGN="LEFT"
840 WIDTH="100%"><TABLE
841 WIDTH="100%"
842 BORDER="0"
843 CELLPADDING="0"
844 CELLSPACING="0"
845 ><TR
846 ><TD
847 WIDTH="33%"
848 ALIGN="left"
849 VALIGN="top"
850 ><A
851 HREF="c1567.html"
852 >Prev</A
853 ></TD
854 ><TD
855 WIDTH="34%"
856 ALIGN="center"
857 VALIGN="top"
858 ><A
859 HREF="index.html"
860 >Home</A
861 ></TD
862 ><TD
863 WIDTH="33%"
864 ALIGN="right"
865 VALIGN="top"
866 ><A
867 HREF="x1812.html"
868 >Next</A
869 ></TD
870 ></TR
871 ><TR
872 ><TD
873 WIDTH="33%"
874 ALIGN="left"
875 VALIGN="top"
876 >Configuring and calling the parser</TD
877 ><TD
878 WIDTH="34%"
879 ALIGN="center"
880 VALIGN="top"
881 ><A
882 HREF="c1567.html"
883 >Up</A
884 ></TD
885 ><TD
886 WIDTH="33%"
887 ALIGN="right"
888 VALIGN="top"
889 >The DTD classes</TD
890 ></TR
891 ></TABLE
892 ></DIV
893 ></BODY
894 ></HTML
895 >