Imported Upstream version 1.7.0
[platform/upstream/augeas.git] / lenses / tests / test_xml.aug
1 (*
2 Module: Test_Xml
3   Provides unit tests and examples for the <Xml> lens.
4 *)
5
6 module Test_Xml =
7
8 (* View: knode
9    A simple flag function
10
11    Parameters:
12     r:regexp - the pattern for the flag
13 *)
14 let knode (r:regexp) = [ key r ]
15
16 (************************************************************************
17  *                          Group: Utilities lens
18  *************************************************************************)
19 (*
20 let _ = print_regexp(lens_ctype(Xml.text))
21 let _ = print_endline ""
22 *)
23
24 (* Group: Comments *)
25
26 (* Test: Xml.comment
27    Comments get mapped into "#comment" nodes. *)
28 test Xml.comment get
29  "<!-- declarations for <head> & <body> -->" =
30
31   { "#comment" = " declarations for <head> & <body> " }
32
33 (* Test: Xml.comment
34    This syntax is not understood. *)
35 test Xml.comment get
36  "<!-- B+, B, or B--->" = *
37
38 (* Group: Prolog and declarations *)
39
40 (* Test: Xml.prolog
41    The XML prolog tag is mapped in a "#declaration" node,
42    which contains an "#attribute" node with various attributes of the tag. *)
43 test Xml.prolog get
44  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" =
45
46   { "#declaration"
47     { "#attribute"
48       { "version" = "1.0" }
49       { "encoding" = "UTF-8" }
50     }
51   }
52
53 (* Test: Xml.decl_def_item
54    !ELEMENT declaration tags are mapped in "!ELEMENT" nodes.
55    The associated declaration attribute is mapped in a "#decl" subnode. *)
56 test Xml.decl_def_item get
57  "<!ELEMENT greeting (#PCDATA)>" =
58
59   { "!ELEMENT" = "greeting"
60     { "#decl" = "(#PCDATA)" }
61   }
62
63 (* Test: Xml.decl_def_item
64    !ENTITY declaration tags are mapped in "!ENTITY" nodes.
65    The associated declaration attribute is mapped in a "#decl" subnode. *)
66 test Xml.decl_def_item get
67  "<!ENTITY da \"&#xD;&#xA;\">" =
68
69   { "!ENTITY" = "da"
70     { "#decl" = "&#xD;&#xA;" }
71   }
72
73 (* Test: Xml.doctype
74    !DOCTYPE tags are mapped in "!DOCTYPE" nodes.
75    The associated system attribute is mapped in a "SYSTEM" subnode. *)
76 test Xml.doctype get
77  "<!DOCTYPE greeting:foo SYSTEM \"hello.dtd\">" =
78
79   { "!DOCTYPE" = "greeting:foo"
80     { "SYSTEM" = "hello.dtd" }
81   }
82
83 (* Test: Xml.doctype
84    This is an example of a !DOCTYPE tag with !ELEMENT children tags. *)
85 test Xml.doctype get "<!DOCTYPE foo [
86 <!ELEMENT bar (#PCDATA)>
87 <!ELEMENT baz (bar)* >
88 ]>" =
89
90   { "!DOCTYPE" = "foo"
91     { "!ELEMENT" = "bar"
92       { "#decl" = "(#PCDATA)" }
93     }
94     { "!ELEMENT" = "baz"
95       { "#decl" = "(bar)*" }
96     }
97   }
98
99 (* Group: Attributes *)
100
101 (* Variable: att_def1 *)
102 let att_def1 = "<!ATTLIST termdef
103 id      ID      #REQUIRED
104 name    CDATA   #IMPLIED>"
105 (* Variable: att_def2 *)
106 let att_def2 = "<!ATTLIST list
107 type    (bullets|ordered|glossary)  \"ordered\">"
108 (* Variable: att_def3 *)
109 let att_def3 = "<!ATTLIST form
110 method  CDATA   #FIXED \"POST\">"
111
112 (* Test: Xml.att_list_def *)
113 test Xml.att_list_def get
114  att_def1 =
115
116   { "!ATTLIST" = "termdef"
117     { "1"
118       { "#name" = "id" }
119       { "#type" = "ID" }
120       { "#REQUIRED" }
121     }
122     { "2"
123       { "#name" = "name" }
124       { "#type" = "CDATA" }
125       { "#IMPLIED" }
126     }
127   }
128
129 (* Test: Xml.att_list_def *)
130 test Xml.att_list_def get
131  att_def2 =
132
133   { "!ATTLIST" = "list"
134     { "1"
135       { "#name" = "type" }
136       { "#type" = "(bullets|ordered|glossary)" }
137       { "#FIXED" = "ordered" }
138     }
139   }
140
141 (* Test: Xml.att_list_def *)
142 test Xml.att_list_def get
143  att_def3 =
144
145   { "!ATTLIST" = "form"
146     { "1"
147       { "#name" = "method" }
148       { "#type" = "CDATA" }
149       { "#FIXED" = "POST" }
150     }
151   }
152
153 (* Test: Xml.notation_def *)
154 test Xml.notation_def get
155  "<!NOTATION not3 SYSTEM \"\">" =
156
157   { "!NOTATION" = "not3"
158     { "SYSTEM" = "" }
159   }
160
161 (* Variable: cdata1 *)
162 let cdata1 = "<![CDATA[testing]]>"
163 (* Test: Xml.cdata *)
164 test Xml.cdata get cdata1 = { "#CDATA" = "testing" }
165
166 (* Variable: attr1 *)
167 let attr1 = " attr1=\"value1\" attr2=\"value2\""
168 (* Variable: attr2 *)
169 let attr2 = " attr2=\"foo\""
170 (* Test: Xml.attributes *)
171 test Xml.attributes get attr1 =
172   { "#attribute"
173     { "attr1" = "value1" }
174     { "attr2" = "value2" }
175   }
176
177 (* Test: Xml.attributes *)
178 test Xml.attributes get " refs=\"A1\nA2  A3\"" =
179   { "#attribute"
180     { "refs" = "A1\nA2  A3" }
181   }
182
183 (* Test: Xml.attributes *)
184 test Xml.attributes put attr1 after rm "/#attribute[1]";
185                                     set "/#attribute/attr2" "foo" = attr2
186
187 (* test quoting *)
188 (* well formed values *)
189 test Xml.attributes get " attr1=\"value1\"" = { "#attribute" { "attr1" = "value1" } }
190 test Xml.attributes get " attr1='value1'" = { "#attribute" { "attr1" = "value1" } }
191 test Xml.attributes get " attr1='va\"lue1'" = { "#attribute" { "attr1" = "va\"lue1" } }
192 test Xml.attributes get " attr1=\"va'lue1\"" = { "#attribute" { "attr1" = "va'lue1" } }
193
194 (* illegal as per the XML standard *)
195 test Xml.attributes get " attr1=\"va\"lue1\"" = *
196 test Xml.attributes get " attr1='va'lue1'" = *
197
198 (* malformed values *)
199 test Xml.attributes get " attr1=\"value1'" = *
200 test Xml.attributes get " attr1='value1\"" = *
201
202 (* Group: empty *)
203
204 (* Variable: empty1 *)
205 let empty1 = "<a/>"
206 (* Variable: empty2 *)
207 let empty2 = "<a foo=\"bar\"/>"
208 (* Variable: empty3 *)
209 let empty3 = "<a foo=\"bar\"></a>\n"
210 (* Variable: empty4 *)
211 let empty4 = "<a foo=\"bar\" far=\"baz\"/>"
212 (* Test: Xml.empty_element *)
213 test Xml.empty_element get empty1 = { "a" = "#empty" }
214 (* Test: Xml.empty_element *)
215 test Xml.empty_element get empty2 =
216   { "a" = "#empty" { "#attribute" { "foo" = "bar"} } }
217
218 (* Test: Xml.empty_element *)
219 test Xml.empty_element put empty1 after set "/a/#attribute/foo" "bar" = empty2
220
221 (* Test: Xml.empty_element
222    The attribute node must be the first child of the element *)
223 test Xml.empty_element put empty1 after set "/a/#attribute/foo" "bar";
224                                         set "/a/#attribute/far" "baz" = empty4
225
226 (* Test: Xml.content *)
227 test Xml.content put "<a><b/></a>" after clear "/a/b" = "<a><b></b>\n</a>"
228
229
230 (* Group: Full lens *)
231
232 (* Test: Xml.lns *)
233 test Xml.lns put "<a></a >" after set "/a/#text[1]" "foo";
234                                  set "/a/#text[2]" "bar" = "<a>foobar</a >"
235
236 (* Test: Xml.lns *)
237 test Xml.lns get "<?xml version=\"1.0\"?>
238 <!DOCTYPE catalog PUBLIC \"-//OASIS//DTD XML Catalogs V1.0//EN\"
239   \"file:///usr/share/xml/schema/xml-core/catalog.dtd\">
240   <doc/>" =
241   { "#declaration"
242   { "#attribute"
243     { "version" = "1.0" }
244   }
245   }
246   { "!DOCTYPE" = "catalog"
247     { "PUBLIC"
248       { "#literal" = "-//OASIS//DTD XML Catalogs V1.0//EN" }
249       { "#literal" = "file:///usr/share/xml/schema/xml-core/catalog.dtd" }
250     }
251   }
252   { "doc" = "#empty" }
253
254 (* Test: Xml.lns *)
255 test Xml.lns get "<oor:component-data xmlns:oor=\"http://openoffice.org/2001/registry\"/>
256 " =
257   { "oor:component-data" = "#empty"
258     { "#attribute"
259       { "xmlns:oor" = "http://openoffice.org/2001/registry" }
260     }
261   }
262
263 (* Variable: input1 *)
264 let input1 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
265 <html>\r
266     <head>
267         <title>Wiki</title>
268     </head>
269     <body>
270         <h1>Augeas</h1>
271         <p class=\"main\">Augeas is now able to parse XML files!</p>
272         <ul>
273             <li>Translate from XML to a tree syntax</li>
274             <li>Translate from the tree back to XML</li> <!-- this is some comment -->
275             <li>this</li>
276         </ul>
277     </body>
278 </html>
279 "
280
281 (* Test: Xml.doc
282    Test <input1> with <Xml.doc> *)
283 test Xml.doc get input1 =
284   { "#declaration"
285     { "#attribute"
286       { "version" = "1.0" }
287       { "encoding" = "UTF-8" }
288     }
289   }
290   { "html"
291     { "#text" = "\r\n    " }
292     { "head"
293       { "#text" = "\n        " }
294       { "title"
295         { "#text" = "Wiki" }
296       }
297       { "#text" = "    " }
298     }
299     { "#text" = "    " }
300     { "body"
301       { "#text" = "
302         " }
303       { "h1"
304         { "#text" = "Augeas" }
305       }
306       { "#text" = "        " }
307       { "p"
308         { "#attribute"
309           { "class" = "main" }
310         }
311         { "#text" = "Augeas is now able to parse XML files!" }
312       }
313       { "#text" = "        " }
314       { "ul"
315         { "#text" = "\n            " }
316         { "li"
317           { "#text" = "Translate from XML to a tree syntax" }
318         }
319         { "#text" = "            " }
320         { "li"
321           { "#text" = "Translate from the tree back to XML" }
322         }
323         { "#text" = " " }
324         { "#comment" = " this is some comment " }
325         { "#text" = "
326             " }
327         { "li"
328           { "#text" = "this" }
329         }
330         { "#text" = "        " }
331       }
332       { "#text" = "    " }
333     }
334   }
335
336 (* Test: Xml.doc
337    Modify <input1> with <Xml.doc> *)
338 test Xml.doc put input1 after rm "/html/body" =
339 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
340 <html>\r
341     <head>
342         <title>Wiki</title>
343     </head>
344     </html>
345 "
346
347
348 (* Variable: ul1 *)
349 let ul1 = "
350 <ul>
351  <li>test1</li>
352   <li>test2</li>
353    <li>test3</li>
354     <li>test4</li>
355 </ul>
356 "
357
358 test Xml.doc get ul1 =
359   { "ul"
360     { "#text" = "
361  " }
362     { "li"
363       { "#text" = "test1" }
364     }
365     { "#text" = "  " }
366     { "li"
367       { "#text" = "test2" }
368     }
369     { "#text" = "   " }
370     { "li"
371       { "#text" = "test3" }
372     }
373     { "#text" = "    " }
374     { "li"
375       { "#text" = "test4" }
376     }
377   }
378
379
380 test Xml.doc put ul1 after set "/ul/li[3]/#text" "bidon" = "
381 <ul>
382  <li>test1</li>
383   <li>test2</li>
384    <li>bidon</li>
385     <li>test4</li>
386 </ul>
387 "
388
389 test Xml.doc put ul1 after rm "/ul/li[2]" = "
390 <ul>
391  <li>test1</li>
392      <li>test3</li>
393     <li>test4</li>
394 </ul>
395 "
396
397
398 (* #text nodes don't move when inserting a node, the result depends on where the node is added *)
399 test Xml.doc put ul1 after insb "a" "/ul/li[2]" = "
400 <ul>
401  <li>test1</li>
402   <a></a>
403 <li>test2</li>
404    <li>test3</li>
405     <li>test4</li>
406 </ul>
407 "
408
409 test Xml.doc put ul1 after insa "a" "/ul/li[1]" = "
410 <ul>
411  <li>test1</li>
412 <a></a>
413   <li>test2</li>
414    <li>test3</li>
415     <li>test4</li>
416 </ul>
417 "
418
419 (* Attributes must be added before text nodes *)
420 test Xml.doc put ul1 after insb "#attribute" "/ul/li[2]/#text";
421                            set "/ul/li[2]/#attribute/bidon" "gazou";
422                            set "/ul/li[2]/#attribute/foo" "bar" = "
423 <ul>
424  <li>test1</li>
425   <li bidon=\"gazou\" foo=\"bar\">test2</li>
426    <li>test3</li>
427     <li>test4</li>
428 </ul>
429 "
430
431 (* if empty element is allowed to be as root, this test triggers error *)
432 test Xml.lns get "<doc>
433 <a><c/><b><c/></b><c/><c/><a></a></a>
434 </doc>" =
435   { "doc"
436     { "#text" = "\n" }
437     { "a"
438       { "c" = "#empty" }
439       { "b"
440         { "c" = "#empty" }
441       }
442       { "c" = "#empty" }
443       { "c" = "#empty" }
444       { "a" }
445     }
446   }
447
448 let p01pass2 = "<?PI before document element?>
449 <!-- comment after document element-->
450 <?PI before document element?>
451 <!-- comment after document element-->
452 <?PI before document element?>
453 <!-- comment after document element-->
454 <?PI before document element?>
455 <!DOCTYPE doc
456 [
457 <!ELEMENT doc ANY>
458 <!ELEMENT a ANY>
459 <!ELEMENT b ANY>
460 <!ELEMENT c ANY>
461 ]>
462 <doc>
463 <a><b><c/></b></a>
464 </doc>
465 <!-- comment after document element-->
466 <?PI after document element?>
467 <!-- comment after document element-->
468 <?PI after document element?>
469 <!-- comment after document element-->
470 <?PI after document element?>
471 "
472
473 test Xml.lns get p01pass2 =
474   { "#pi"
475     { "#target" = "PI" }
476     { "#instruction" = "before document element" }
477   }
478   { "#comment" = " comment after document element" }
479   { "#pi"
480     { "#target" = "PI" }
481     { "#instruction" = "before document element" }
482   }
483   { "#comment" = " comment after document element" }
484   { "#pi"
485     { "#target" = "PI" }
486     { "#instruction" = "before document element" }
487   }
488   { "#comment" = " comment after document element" }
489   { "#pi"
490     { "#target" = "PI" }
491     { "#instruction" = "before document element" }
492   }
493   { "!DOCTYPE" = "doc"
494     { "!ELEMENT" = "doc"
495       { "#decl" = "ANY" }
496     }
497     { "!ELEMENT" = "a"
498       { "#decl" = "ANY" }
499     }
500     { "!ELEMENT" = "b"
501       { "#decl" = "ANY" }
502     }
503     { "!ELEMENT" = "c"
504       { "#decl" = "ANY" }
505     }
506   }
507   { "doc"
508     { "#text" = "
509 " }
510     { "a"
511       { "b"
512         { "c" = "#empty" }
513       }
514     }
515   }
516   { "#comment" = " comment after document element" }
517   { "#pi"
518     { "#target" = "PI" }
519     { "#instruction" = "after document element" }
520   }
521   { "#comment" = " comment after document element" }
522   { "#pi"
523     { "#target" = "PI" }
524     { "#instruction" = "after document element" }
525   }
526   { "#comment" = " comment after document element" }
527   { "#pi"
528     { "#target" = "PI" }
529     { "#instruction" = "after document element" }
530   }
531
532
533 (* various valid Name constructions *)
534 test Xml.lns get "<doc>\n<A:._-0/>\n<::._-0/>\n<_:._-0/>\n<A/>\n<_/>\n<:/>\n</doc>" =
535   { "doc"
536     { "#text" = "\n" }
537     { "A:._-0" = "#empty" }
538     { "::._-0" = "#empty" }
539     { "_:._-0" = "#empty" }
540     { "A" = "#empty" }
541     { "_" = "#empty" }
542     { ":" = "#empty" }
543   }
544
545 test Xml.lns get "<doc>
546 <abcdefghijklmnopqrstuvwxyz/>
547 <ABCDEFGHIJKLMNOPQRSTUVWXYZ/>
548 <A01234567890/>
549 <A.-:/>
550 </doc>" =
551   { "doc"
552     { "#text" = "\n" }
553     { "abcdefghijklmnopqrstuvwxyz" = "#empty" }
554     { "ABCDEFGHIJKLMNOPQRSTUVWXYZ" = "#empty" }
555     { "A01234567890" = "#empty" }
556     { "A.-:" = "#empty" }
557   }
558
559
560 let p06fail1 = "<!--non-validating processors may pass this instance because they don't check the IDREFS attribute type-->
561 <!DOCTYPE doc
562 [
563 <!ELEMENT doc (a|refs)*>
564 <!ELEMENT a EMPTY>
565 <!ELEMENT refs EMPTY>
566 <!ATTLIST refs refs IDREFS #REQUIRED>
567 <!ATTLIST a id ID #REQUIRED>
568 ]>
569 <doc>
570 <a id=\"A1\"/><a id=\"A2\"/><a id=\"A3\"/>
571 <refs refs=\"\"/>
572 </doc>"
573
574 (* we accept this test because we do not verify XML references *)
575 test Xml.lns get p06fail1 =
576   { "#comment" = "non-validating processors may pass this instance because they don't check the IDREFS attribute type" }
577   { "!DOCTYPE" = "doc"
578     { "!ELEMENT" = "doc"
579       { "#decl" = "(a|refs)*" }
580     }
581     { "!ELEMENT" = "a"
582       { "#decl" = "EMPTY" }
583     }
584     { "!ELEMENT" = "refs"
585       { "#decl" = "EMPTY" }
586     }
587     { "!ATTLIST" = "refs"
588       { "1"
589         { "#name" = "refs" }
590         { "#type" = "IDREFS" }
591         { "#REQUIRED" }
592       }
593     }
594     { "!ATTLIST" = "a"
595       { "1"
596         { "#name" = "id" }
597         { "#type" = "ID" }
598         { "#REQUIRED" }
599       }
600     }
601   }
602   { "doc"
603     { "#text" = "
604 " }
605     { "a" = "#empty"
606       { "#attribute"
607         { "id" = "A1" }
608       }
609     }
610     { "a" = "#empty"
611       { "#attribute"
612         { "id" = "A2" }
613       }
614     }
615     { "a" = "#empty"
616       { "#attribute"
617         { "id" = "A3" }
618       }
619     }
620     { "refs" = "#empty"
621       { "#attribute"
622         { "refs" = "" }
623       }
624     }
625   }
626
627 (* we accept dquote, but not single quotes, because of resulting ambiguity *)
628 let p10pass1_1 = "<doc><A a=\"asdf>'&#34;>\nasdf\n    ?>%\"/></doc>"
629 let p10pass1_2 = "<doc><A a='\"\">&#39;&#34;'/></doc>"
630
631 test Xml.lns get p10pass1_1 =
632   { "doc"
633     { "A" = "#empty"
634       { "#attribute"
635         { "a" = "asdf>'&#34;>\nasdf\n    ?>%" }
636       }
637     }
638   }
639
640 test Xml.lns get p10pass1_2 =
641   { "doc"
642     { "A" = "#empty"
643       { "#attribute"
644         { "a" = "\"\">&#39;&#34;" }
645       }
646     }
647   }
648
649 (* here again, test exclude single quote *)
650 let p11pass1 = "<!--Inability to resolve a notation should not be reported as an error-->
651 <!DOCTYPE doc
652 [
653 <!ELEMENT doc EMPTY>
654 <!NOTATION not1 SYSTEM \"a%a&b&#0<!ELEMENT<!--<?</>?>/\''\">
655 <!NOTATION not3 SYSTEM \"\">
656 ]>
657 <doc></doc>"
658
659 test Xml.lns get p11pass1 =
660   { "#comment" = "Inability to resolve a notation should not be reported as an error" }
661   { "!DOCTYPE" = "doc"
662     { "!ELEMENT" = "doc"
663       { "#decl" = "EMPTY" }
664     }
665     { "!NOTATION" = "not1"
666       { "SYSTEM" = "a%a&b&#0<!ELEMENT<!--<?</>?>/\''" }
667     }
668     { "!NOTATION" = "not3"
669       { "SYSTEM" = "" }
670     }
671   }
672   { "doc" }
673
674 test Xml.lns get "<doc>a%b%&lt;/doc>&#60;/doc>]]&lt;&amp;</doc>" =
675   { "doc"
676     { "#text" = "a%b%&lt;/doc>&#60;/doc>]]&lt;&amp;" }
677   }
678
679 let p15pass1 = "<!--a
680 <!DOCTYPE
681 <?-
682 ]]>-<[ CDATA [
683 \"- -'-
684 -<doc>-->
685 <!---->
686 <doc></doc>"
687
688 test Xml.lns get p15pass1 =
689   { "#comment" = "a
690 <!DOCTYPE
691 <?-
692 ]]>-<[ CDATA [
693 \"- -'-
694 -<doc>" }
695   { "#comment" = "" }
696   { "doc" }
697
698 let p22pass3 = "<?xml version=\"1.0\"?>
699 <!--comment--> <?pi some instruction ?>
700 <doc><?pi?></doc>"
701
702 test Xml.lns get p22pass3 =
703   { "#declaration"
704     { "#attribute"
705       { "version" = "1.0" }
706     }
707   }
708   { "#comment" = "comment" }
709   { "#pi"
710     { "#target" = "pi" }
711     { "#instruction" = "some instruction" }
712   }
713   { "doc"
714     { "#pi"
715       { "#target" = "pi" }
716     }
717   }
718
719 let p25pass2 = "<?xml version
720
721
722 =
723
724
725 \"1.0\"?>
726 <doc></doc>"
727
728 test Xml.lns get p25pass2 =
729   { "#declaration"
730     { "#attribute"
731       { "version" = "1.0" }
732     }
733   }
734   { "doc" }
735
736
737 test Xml.lns get "<!DOCTYPE
738
739 doc
740
741 [
742 <!ELEMENT doc EMPTY>
743 ]>
744 <doc></doc>" =
745   { "!DOCTYPE" = "doc"
746     { "!ELEMENT" = "doc"
747       { "#decl" = "EMPTY" }
748     }
749   }
750   { "doc" }
751
752 test Xml.lns get "<doc></doc  \n>" = { "doc" }
753
754 test Xml.lns get "<a><doc att=\"val\" \natt2=\"val2\" att3=\"val3\"/></a>" =
755   { "a"
756     { "doc" = "#empty"
757       { "#attribute"
758         { "att" = "val" }
759         { "att2" = "val2" }
760         { "att3" = "val3" }
761       }
762     }
763   }
764
765 test Xml.lns get "<doc/>" = { "doc" = "#empty" }
766
767 test Xml.lns get "<a><![CDATA[Thu, 13 Feb 2014 12:22:35 +0000]]></a>" =
768   { "a"
769     { "#CDATA" = "Thu, 13 Feb 2014 12:22:35 +0000" } }
770
771 (* failure tests *)
772 (* only one document element *)
773 test Xml.lns get "<doc></doc><bad/>" = *
774
775 (* document element must be complete *)
776 test Xml.lns get "<doc>" = *
777
778 (* accept empty document *)
779 test Xml.lns get "\n" = {}
780
781 (* malformed element *)
782 test Xml.lns get "<a><A@/></a>" = *
783
784 (* a Name cannot start with a digit *)
785 test Xml.lns get "<a><0A/></a>" = *
786
787 (* no space before "CDATA" *)
788 test Xml.lns get "<doc><![ CDATA[a]]></doc>" = *
789
790 (* no space after "CDATA" *)
791 test Xml.lns get "<doc><![CDATA [a]]></doc>" = *
792
793 (* FIXME: CDSect's can't nest *)
794 test Xml.lns get "<doc>
795 <![CDATA[
796 <![CDATA[XML doesn't allow CDATA sections to nest]]>
797 ]]>
798 </doc>" =
799   { "doc"
800     { "#text" = "\n" }
801     { "#CDATA" = "\n<![CDATA[XML doesn't allow CDATA sections to nest" }
802     { "#text" = "\n]]" }
803     { "#text" = ">\n" } }
804
805 (* Comment is illegal in VersionInfo *)
806 test Xml.lns get "<?xml version <!--bad comment--> =\"1.0\"?>
807 <doc></doc>" = *
808
809 (* only declarations in DTD *)
810 test Xml.lns get "<!DOCTYPE doc [
811 <!ELEMENT doc EMPTY>
812 <doc></doc>
813 ]>" = *
814
815 (* we do not support external entities *)
816 test Xml.lns get "<!DOCTYPE doc [
817 <!ENTITY % eldecl \"<!ELEMENT doc EMPTY>\">
818 %eldecl;
819 ]>
820 <doc></doc>" = *
821
822 (* Escape character in attributes *)
823 test Xml.lns get "<a password=\"my\!pass\" />" =
824   { "a" = "#empty"
825     { "#attribute" { "password" = "my\!pass" } } }
826
827 test Xml.lns put ""
828 after set "/a" "#empty" = "<a/>\n"