2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / Commons.Xml.Relaxng / Commons.Xml.Relaxng / RelaxngReader.cs
blob12899021b727d1486bd1c26e0efad06037d03ca1
1 //
2 // Commons.Xml.Relaxng.RelaxngReader.cs
3 //
4 // Author:
5 // Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
6 //
7 // 2003 Atsushi Enomoto "No rights reserved."
8 //
9 // Copyright (c) 2004 Novell Inc.
10 // All rights reserved
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 //
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 //
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System;
35 using System.Collections;
36 using System.Xml;
38 namespace Commons.Xml.Relaxng
40 public class RelaxngReader : XmlDefaultReader
42 // static members.
43 static RelaxngPattern grammarForRelaxng;
44 static XmlReader relaxngXmlReader;
45 static RelaxngReader ()
47 relaxngXmlReader = new XmlTextReader (typeof (RelaxngReader).Assembly.GetManifestResourceStream ("relaxng.rng"));
48 grammarForRelaxng =
49 RelaxngPattern.Read (relaxngXmlReader);
52 [Obsolete] // incorrectly introduced
53 public static string RelaxngNS = "http://relaxng.org/ns/structure/1.0";
54 public static RelaxngPattern GrammarForRelaxng {
55 get { return grammarForRelaxng; }
59 // fields
60 Stack nsStack = new Stack ();
61 Stack datatypeLibraryStack = new Stack ();
62 XmlResolver resolver;
63 bool skipExternal = true;
64 // ArrayList annotationNamespaces = new ArrayList ();
66 // ctor
67 public RelaxngReader (XmlReader reader)
68 : this (reader, null)
72 public RelaxngReader (XmlReader reader, string ns)
73 : this (reader, ns, new XmlUrlResolver ())
77 public RelaxngReader (XmlReader reader, string ns, XmlResolver resolver)
78 // : base (grammarForRelaxng == null ? reader : new RelaxngValidatingReader (reader, grammarForRelaxng))
79 : base (reader)
81 this.resolver = resolver;
82 if (Reader.ReadState == ReadState.Initial)
83 Read ();
84 MoveToContent ();
85 string nsval = GetSpaceStrippedAttribute ("ns", String.Empty);
86 if (nsval == null)
87 nsval = ns;
88 nsStack.Push (nsval == null ? String.Empty : nsval);
89 string dtlib = GetSpaceStrippedAttribute ("datatypeLibrary", String.Empty);
90 datatypeLibraryStack.Push (dtlib != null ?
91 dtlib : String.Empty);
94 public XmlResolver XmlResolver {
95 set { resolver = value; }
98 internal XmlResolver Resolver {
99 get { return resolver; }
102 private void FillLocation (RelaxngElementBase el)
104 el.BaseUri = BaseURI;
105 IXmlLineInfo li = this as IXmlLineInfo;
106 el.LineNumber = li != null ? li.LineNumber : 0;
107 el.LinePosition = li != null ? li.LinePosition : 0;
111 public void AddAnnotationNamespace (string ns)
113 if (!annotationNamespaces.Contains (ns))
114 annotationNamespaces.Add (ns);
118 // public
119 public override bool Read ()
121 bool skipRead = false;
122 bool b = false;
123 bool loop = true;
124 MoveToElement ();
125 if (IsEmptyElement || NodeType == XmlNodeType.EndElement) { // this should be done here
126 nsStack.Pop ();
127 datatypeLibraryStack.Pop ();
129 do {
130 if (!skipRead)
131 b = Reader.Read ();
132 else
133 skipRead = false;
134 switch (NodeType) {
135 case XmlNodeType.ProcessingInstruction:
136 case XmlNodeType.Comment:
137 case XmlNodeType.EntityReference:
138 continue;
139 case XmlNodeType.Whitespace:
140 // Skip whitespaces except for data and param.
141 case XmlNodeType.SignificantWhitespace:
142 if (LocalName != "value" && LocalName != "param") {
143 continue;
145 else
146 loop = false;
147 break;
148 case XmlNodeType.Element:
149 case XmlNodeType.EndElement:
150 if (!skipExternal)
151 goto default;
152 if (NamespaceURI != RelaxngGrammar.NamespaceURI) {
153 Reader.Skip ();
154 skipRead = true;
156 else
157 loop = false;
158 break;
159 default:
160 loop = false;
161 break;
163 } while (!Reader.EOF && loop);
165 switch (NodeType) {
166 case XmlNodeType.Element:
167 if (MoveToAttribute ("ns")) {
168 nsStack.Push (Value.Trim ());
169 MoveToElement ();
171 else
172 nsStack.Push (ContextNamespace);
174 if (MoveToAttribute ("datatypeLibrary")) {
175 string uriString = Value.Trim ();
176 if (uriString.Length == 0)
177 datatypeLibraryStack.Push (String.Empty);
178 else {
179 try {
180 Uri uri = new Uri (uriString);
181 // MS.NET Uri is too lamespec
182 datatypeLibraryStack.Push (uri.ToString ());
183 } catch (UriFormatException ex) {
184 throw new RelaxngException (ex.Message, ex);
187 MoveToElement ();
189 else
190 datatypeLibraryStack.Push (DatatypeLibrary);
191 break;
194 return b;
197 // Properties
199 public string ContextNamespace {
200 get {
201 if (nsStack.Count == 0)
202 // It happens only on initialization.
203 return String.Empty;
204 return nsStack.Peek () as string;
208 public string DatatypeLibrary {
209 get {
210 if (datatypeLibraryStack.Count == 0)
211 // It happens only on initialization.
212 return String.Empty;
213 return datatypeLibraryStack.Peek () as string;
217 // Utility methods.
218 private void expect (string name)
220 if (NamespaceURI != RelaxngGrammar.NamespaceURI)
221 throw new RelaxngException (String.Format ("Invalid document: expected namespace {0} but found {1}", RelaxngGrammar.NamespaceURI, NamespaceURI));
222 else if (LocalName != name)
223 throw new RelaxngException (String.Format ("Invalid document: expected local name {0} but found {1}", name, LocalName));
226 private void expectEnd (string name)
228 if (NodeType != XmlNodeType.EndElement)
229 throw new RelaxngException (String.Format ("Expected EndElement but found {0}.", NodeType));
230 expect (name);
232 Read ();
235 // Other than name class and pattern.
236 private RelaxngStart ReadStart ()
238 RelaxngStart s = new RelaxngStart ();
239 FillLocation (s);
240 expect ("start");
242 if (MoveToFirstAttribute ()) {
243 do {
244 if (NamespaceURI != String.Empty)
245 continue;
246 switch (LocalName) {
247 case "datatypeLibrary":
248 case "combine":
249 break;
250 default:
251 throw new RelaxngException ("Invalid attribute.");
253 } while (MoveToNextAttribute ());
254 MoveToElement ();
257 if (MoveToAttribute ("combine")) {
258 s.Combine = Value.Trim ();
259 if (s.Combine != "choice" && s.Combine != "interleave")
260 throw new RelaxngException ("Invalid combine attribute: " + s.Combine);
263 MoveToElement ();
264 Read ();
265 s.Pattern = ReadPattern ();
266 expectEnd ("start");
267 return s;
270 private string GetNameAttribute ()
272 string name = GetSpaceStrippedAttribute ("name", String.Empty);
273 if (name == null)
274 throw new RelaxngException ("Required attribute name is not found.");
275 return XmlConvert.VerifyNCName (name);
278 private string GetSpaceStrippedAttribute (string name, string ns)
280 string v = GetAttribute (name, ns);
281 return v != null ? v.Trim () : null;
284 private RelaxngDefine ReadDefine ()
286 RelaxngDefine def = new RelaxngDefine ();
287 FillLocation (def);
288 expect ("define");
289 def.Name = GetNameAttribute ();
290 def.Combine = GetSpaceStrippedAttribute ("combine", String.Empty);
292 Read ();
293 while (NodeType == XmlNodeType.Element)
294 def.Patterns.Add (ReadPattern ());
295 expectEnd ("define");
296 return def;
299 private RelaxngParam ReadParam ()
301 RelaxngParam p = new RelaxngParam ();
302 FillLocation (p);
303 expect ("param");
304 p.Name = GetNameAttribute ();
305 p.Value = ReadString ().Trim ();
306 expectEnd ("param");
307 return p;
310 // NameClass reader (only if it is element-style.)
311 private RelaxngNameClass ReadNameClass ()
313 switch (LocalName) {
314 case "name":
315 return ReadNameClassName ();
316 case "anyName":
317 return ReadNameClassAnyName ();
318 case "nsName":
319 return ReadNameClassNsName ();
320 case "choice":
321 return ReadNameClassChoice ();
323 throw new RelaxngException ("Invalid name class: " + LocalName);
326 private RelaxngName ReadNameClassName ()
328 string name = ReadString ().Trim ();
329 RelaxngName rName = resolvedName (name);
330 expectEnd ("name");
331 return rName;
334 private RelaxngAnyName ReadNameClassAnyName ()
336 RelaxngAnyName an = new RelaxngAnyName ();
337 FillLocation (an);
338 if (!IsEmptyElement) {
339 Read ();
340 if (NodeType == XmlNodeType.EndElement) {
341 } else {
342 // expect except
343 expect ("except");
344 Read ();
345 an.Except = new RelaxngExceptNameClass ();
346 FillLocation (an.Except);
347 while (NodeType == XmlNodeType.Element)
348 an.Except.Names.Add (
349 ReadNameClass ());
350 expectEnd ("except");
352 expectEnd ("anyName");
353 } else
354 Read ();
355 return an;
358 private RelaxngNsName ReadNameClassNsName ()
360 RelaxngNsName nn = new RelaxngNsName ();
361 FillLocation (nn);
362 nn.Namespace = this.ContextNamespace;
363 if (!IsEmptyElement) {
364 Read ();
365 if (NodeType == XmlNodeType.EndElement) {
366 } else {
367 // expect except
368 expect ("except");
369 // Read ();
370 nn.Except = ReadNameClassExcept ();//new RelaxngExceptNameClass ();
371 FillLocation (nn.Except);
373 expectEnd ("nsName");
374 } else
375 Read ();
376 return nn;
379 private RelaxngNameChoice ReadNameClassChoice ()
381 RelaxngNameChoice nc = new RelaxngNameChoice ();
382 FillLocation (nc);
383 if (IsEmptyElement)
384 throw new RelaxngException ("Name choice must have at least one name class.");
386 Read ();
387 while (NodeType != XmlNodeType.EndElement) {
388 nc.Children.Add (ReadNameClass ());
390 if (nc.Children.Count == 0)
391 throw new RelaxngException ("Name choice must have at least one name class.");
393 expectEnd ("choice");
394 return nc;
397 private RelaxngExceptNameClass ReadNameClassExcept ()
399 RelaxngExceptNameClass x = new RelaxngExceptNameClass ();
400 FillLocation (x);
401 if (IsEmptyElement)
402 throw new RelaxngException ("Name choice must have at least one name class.");
404 Read ();
405 while (NodeType != XmlNodeType.EndElement)
406 x.Names.Add (ReadNameClass ());
407 if (x.Names.Count == 0)
408 throw new RelaxngException ("Name choice must have at least one name class.");
410 expectEnd ("except");
411 return x;
414 // Pattern reader
416 public RelaxngPattern ReadPattern ()
418 while (NodeType != XmlNodeType.Element)
419 if (!Read ())
420 throw new RelaxngException ("RELAX NG pattern did not appear.");
422 switch (LocalName) {
423 case "element":
424 return ReadElementPattern ();
425 case "attribute":
426 return ReadAttributePattern ();
427 case "group":
428 return ReadGroupPattern ();
429 case "interleave":
430 return ReadInterleavePattern ();
431 case "choice":
432 return ReadChoicePattern ();
433 case "optional":
434 return ReadOptionalPattern ();
435 case "zeroOrMore":
436 return ReadZeroOrMorePattern ();
437 case "oneOrMore":
438 return ReadOneOrMorePattern ();
439 case "list":
440 return ReadListPattern ();
441 case "mixed":
442 return ReadMixedPattern ();
443 case "ref":
444 return ReadRefPattern ();
445 case "parentRef":
446 return ReadParentRefPattern ();
447 case "empty":
448 return ReadEmptyPattern ();
449 case "text":
450 return ReadTextPattern ();
451 case "data":
452 return ReadDataPattern ();
453 case "value":
454 return ReadValuePattern ();
455 case "notAllowed":
456 return ReadNotAllowedPattern ();
457 case "externalRef":
458 return ReadExternalRefPattern ();
459 case "grammar":
460 return ReadGrammarPattern ();
462 throw new RelaxngException ("Non-supported pattern specification: " + LocalName);
465 private void ReadPatterns (RelaxngSingleContentPattern el)
467 do {
468 el.Patterns.Add (ReadPattern ());
469 } while (NodeType == XmlNodeType.Element);
472 private void ReadPatterns (RelaxngBinaryContentPattern el)
474 do {
475 el.Patterns.Add (ReadPattern ());
476 } while (NodeType == XmlNodeType.Element);
479 private RelaxngExcept ReadPatternExcept ()
481 RelaxngExcept x = new RelaxngExcept ();
482 FillLocation (x);
483 if (IsEmptyElement)
484 throw new RelaxngException ("'except' must have at least one pattern.");
485 Read ();
486 while (NodeType != XmlNodeType.EndElement)
487 x.Patterns.Add (ReadPattern ());
488 if (x.Patterns.Count == 0)
489 throw new RelaxngException ("'except' must have at least one pattern.");
491 expectEnd ("except");
492 return x;
495 private RelaxngInclude ReadInclude ()
497 RelaxngInclude i = new RelaxngInclude ();
498 FillLocation (i);
499 expect ("include");
500 i.NSContext = ContextNamespace;
501 string href = GetSpaceStrippedAttribute ("href", String.Empty);
502 if (href == null)
503 throw new RelaxngException ("Required attribute href was not found.");
504 XmlResolver res = resolver != null ? resolver : new XmlUrlResolver ();
505 i.Href = res.ResolveUri (BaseURI != null ? new Uri (BaseURI) : null, href).AbsoluteUri;
506 if (!IsEmptyElement) {
507 Read ();
508 this.readGrammarIncludeContent (i.Starts, i.Defines, i.Divs, null);
509 expectEnd ("include");
511 else
512 Read ();
513 return i;
516 private void readGrammarIncludeContent (IList starts, IList defines, IList divs, IList includes)
518 while (NodeType == XmlNodeType.Element) {
519 switch (LocalName) {
520 case "start":
521 starts.Add (ReadStart ());
522 break;
523 case "define":
524 defines.Add (ReadDefine ());
525 break;
526 case "div":
527 divs.Add (ReadDiv (includes != null));
528 break;
529 case "include":
530 if (includes != null)
531 includes.Add (ReadInclude ());
532 else
533 throw new RelaxngException ("Unexpected content: " + Name);
534 break;
535 default:
536 throw new RelaxngException ("Unexpected content: " + Name);
541 private RelaxngDiv ReadDiv (bool allowIncludes)
543 expect ("div");
544 RelaxngDiv div = new RelaxngDiv ();
545 FillLocation (div);
546 if (!IsEmptyElement) {
547 Read ();
548 readGrammarIncludeContent (div.Starts, div.Defines, div.Divs, div.Includes);
549 expectEnd ("div");
551 else
552 Read ();
553 return div;
556 private RelaxngName resolvedName (string nameSpec)
558 int colonAt = nameSpec.IndexOf (':');
559 string prefix = (colonAt < 0) ? "" : nameSpec.Substring (0, colonAt);
560 string local = (colonAt < 0) ? nameSpec : nameSpec.Substring (colonAt + 1, nameSpec.Length - colonAt - 1);
561 string uri = ContextNamespace;
563 if (prefix != "") {
564 uri = LookupNamespace (prefix);
565 if (uri == null)
566 throw new RelaxngException ("Undeclared prefix in name component: " + nameSpec);
568 RelaxngName n = new RelaxngName (local, uri);
569 FillLocation (n);
570 return n;
573 private RelaxngElement ReadElementPattern ()
575 RelaxngElement el = new RelaxngElement ();
576 FillLocation (el);
578 if (MoveToFirstAttribute ()) {
579 do {
580 if (NamespaceURI != String.Empty)
581 continue;
582 switch (LocalName) {
583 case "datatypeLibrary":
584 case "name":
585 case "ns":
586 break;
587 default:
588 throw new RelaxngException ("Invalid attribute.");
590 } while (MoveToNextAttribute ());
591 MoveToElement ();
594 // try to get name from attribute.
595 if (MoveToAttribute ("name"))
596 el.NameClass = resolvedName (XmlConvert.VerifyName (Value.Trim ()));
597 MoveToElement ();
598 Read ();
600 // read nameClass from content.
601 if (el.NameClass == null)
602 el.NameClass = ReadNameClass ();
604 // read patterns.
605 this.ReadPatterns (el);
607 expectEnd ("element");
609 if (el.NameClass == null)
610 throw new RelaxngException ("Name class was not specified.");
611 return el;
614 private RelaxngAttribute ReadAttributePattern ()
616 RelaxngAttribute attr = new RelaxngAttribute ();
617 FillLocation (attr);
619 if (MoveToFirstAttribute ()) {
620 do {
621 if (NamespaceURI != String.Empty)
622 continue;
623 switch (LocalName) {
624 case "datatypeLibrary":
625 case "name":
626 case "ns":
627 break;
628 default:
629 throw new RelaxngException ("Invalid attribute.");
631 } while (MoveToNextAttribute ());
632 MoveToElement ();
635 string ns = GetSpaceStrippedAttribute ("ns", String.Empty);
637 // try to get name from attribute.
638 if (MoveToAttribute ("name", String.Empty)) {
639 // attr.NameClass = resolvedName (XmlConvert.VerifyName (Value.Trim ()), false);
640 RelaxngName nc = new RelaxngName ();
641 string name = XmlConvert.VerifyName (Value.Trim ());
642 if (name.IndexOf (':') > 0)
643 nc = resolvedName (name);
644 else {
645 nc.LocalName = name;
646 nc.Namespace = ns == null ? String.Empty : ns;
648 attr.NameClass = nc;
651 MoveToElement ();
652 if (!IsEmptyElement) {
653 Read ();
654 // read nameClass from content.
655 if (attr.NameClass == null)
656 attr.NameClass = ReadNameClass ();
658 if (NodeType == XmlNodeType.Element)
659 attr.Pattern = ReadPattern ();
661 expectEnd ("attribute");
662 } else
663 Read ();
665 if (attr.NameClass == null)
666 throw new RelaxngException ("Name class was not specified.");
667 return attr;
670 private RelaxngGrammar ReadGrammarPattern ()
672 RelaxngGrammar grammar = new RelaxngGrammar ();
673 FillLocation (grammar);
674 grammar.DefaultNamespace = Reader.GetAttribute ("ns");
675 Read ();
676 this.readGrammarIncludeContent (grammar.Starts, grammar.Defines, grammar.Divs, grammar.Includes);
677 expectEnd ("grammar");
679 return grammar;
682 private RelaxngRef ReadRefPattern ()
684 RelaxngRef r = new RelaxngRef ();
685 FillLocation (r);
686 expect ("ref");
687 r.Name = GetNameAttribute ();
688 if (!IsEmptyElement) {
689 Read ();
690 expectEnd ("ref");
692 else
693 Read ();
694 return r;
697 private RelaxngExternalRef ReadExternalRefPattern ()
699 RelaxngExternalRef r = new RelaxngExternalRef ();
700 FillLocation (r);
701 expect ("externalRef");
702 string href = GetSpaceStrippedAttribute ("href", String.Empty);
703 if (href == null)
704 throw new RelaxngException ("Required attribute href was not found.");
705 XmlResolver res = resolver != null ? resolver : new XmlUrlResolver ();
706 r.Href = res.ResolveUri (BaseURI != null ? new Uri (BaseURI) : null, href).AbsoluteUri;
707 r.NSContext = ContextNamespace;
708 if (!IsEmptyElement) {
709 Read ();
710 expectEnd ("externalRef");
712 else
713 Read ();
714 return r;
717 private RelaxngParentRef ReadParentRefPattern ()
719 RelaxngParentRef r = new RelaxngParentRef ();
720 FillLocation (r);
721 expect ("parentRef");
722 r.Name = GetNameAttribute ();
723 if (!IsEmptyElement) {
724 Read ();
725 expectEnd ("parentRef");
727 else
728 Read ();
729 return r;
732 private RelaxngEmpty ReadEmptyPattern ()
734 expect ("empty");
736 if (MoveToFirstAttribute ()) {
737 do {
738 if (NamespaceURI == String.Empty && LocalName != "datatypeLibrary")
739 throw new RelaxngException ("Invalid attribute.");
740 } while (MoveToNextAttribute ());
741 MoveToElement ();
744 if (!IsEmptyElement) {
745 Read ();
746 expectEnd ("empty");
748 else
749 Read ();
751 RelaxngEmpty empty = new RelaxngEmpty ();
752 FillLocation (empty);
753 return empty;
756 private RelaxngText ReadTextPattern ()
758 expect ("text");
760 if (MoveToFirstAttribute ()) {
761 do {
762 if (NamespaceURI == String.Empty && LocalName != "datatypeLibrary")
763 throw new RelaxngException ("Invalid attribute.");
764 } while (MoveToNextAttribute ());
765 MoveToElement ();
768 if (!IsEmptyElement) {
769 Read ();
770 expectEnd ("text");
772 else
773 Read ();
775 RelaxngText t = new RelaxngText ();
776 FillLocation (t);
777 return t;
780 private RelaxngData ReadDataPattern ()
782 RelaxngData data = new RelaxngData ();
783 FillLocation (data);
785 expect ("data");
786 data.Type = GetSpaceStrippedAttribute ("type", String.Empty);
787 if (data.Type == null)
788 throw new RelaxngException ("Attribute type is required.");
789 data.DatatypeLibrary = DatatypeLibrary;
791 if (MoveToFirstAttribute ()) {
792 do {
793 if (NamespaceURI != String.Empty)
794 continue;
795 switch (LocalName) {
796 case "datatypeLibrary":
797 case "type":
798 break;
799 default:
800 throw new RelaxngException ("Invalid attribute.");
802 } while (MoveToNextAttribute ());
803 MoveToElement ();
806 if (!IsEmptyElement) {
807 Read ();
808 while (Name == "param") {
809 data.ParamList.Add (ReadParam ());
811 if (LocalName == "except")
812 data.Except = ReadPatternExcept ();
813 expectEnd ("data");
814 } else
815 Read ();
817 return data;
820 private RelaxngValue ReadValuePattern ()
822 RelaxngValue v = new RelaxngValue ();
823 FillLocation (v);
824 expect ("value");
826 if (MoveToFirstAttribute ()) {
827 do {
828 if (NamespaceURI != String.Empty)
829 continue;
830 switch (LocalName) {
831 case "datatypeLibrary":
832 case "type":
833 case "ns":
834 break;
835 default:
836 throw new RelaxngException ("Invalid attribute.");
838 } while (MoveToNextAttribute ());
839 MoveToElement ();
842 if (MoveToAttribute ("type")) {
843 v.Type = Value.Trim ();
844 v.DatatypeLibrary = DatatypeLibrary;
845 } else {
846 v.Type = "token";
847 v.DatatypeLibrary = "";
849 // v.Namespace = GetSpaceStrippedAttribute ("ns", String.Empty);
850 MoveToElement ();
851 if (IsEmptyElement) {
852 v.Value = String.Empty;
853 Read ();
854 } else {
855 v.Value = ReadString ();
856 expectEnd ("value");
859 return v;
862 private RelaxngList ReadListPattern ()
864 RelaxngList list = new RelaxngList ();
865 FillLocation (list);
866 expect ("list");
867 Read ();
868 ReadPatterns (list);
869 expectEnd ("list");
870 return list;
873 private RelaxngOneOrMore ReadOneOrMorePattern ()
875 RelaxngOneOrMore o = new RelaxngOneOrMore ();
876 FillLocation (o);
877 expect ("oneOrMore");
878 Read ();
879 ReadPatterns (o);
880 expectEnd ("oneOrMore");
881 return o;
884 private RelaxngZeroOrMore ReadZeroOrMorePattern ()
886 RelaxngZeroOrMore o = new RelaxngZeroOrMore ();
887 FillLocation (o);
888 expect ("zeroOrMore");
889 Read ();
890 ReadPatterns (o);
891 expectEnd ("zeroOrMore");
892 return o;
895 private RelaxngOptional ReadOptionalPattern ()
897 RelaxngOptional o = new RelaxngOptional ();
898 FillLocation (o);
899 expect ("optional");
900 Read ();
901 ReadPatterns (o);
902 expectEnd ("optional");
903 return o;
906 private RelaxngMixed ReadMixedPattern ()
908 RelaxngMixed o = new RelaxngMixed ();
909 FillLocation (o);
910 expect ("mixed");
911 Read ();
912 ReadPatterns (o);
913 expectEnd ("mixed");
914 return o;
917 private RelaxngGroup ReadGroupPattern ()
919 RelaxngGroup g = new RelaxngGroup ();
920 FillLocation (g);
921 expect ("group");
922 Read ();
923 ReadPatterns (g);
924 expectEnd ("group");
925 return g;
928 private RelaxngInterleave ReadInterleavePattern ()
930 RelaxngInterleave i = new RelaxngInterleave ();
931 FillLocation (i);
932 expect ("interleave");
933 Read ();
934 ReadPatterns (i);
935 expectEnd ("interleave");
936 return i;
939 private RelaxngChoice ReadChoicePattern ()
941 RelaxngChoice c = new RelaxngChoice ();
942 FillLocation (c);
943 expect ("choice");
944 Read ();
945 ReadPatterns (c);
946 expectEnd ("choice");
947 return c;
950 private RelaxngNotAllowed ReadNotAllowedPattern ()
952 expect ("notAllowed");
953 if (!IsEmptyElement) {
954 Read ();
955 expectEnd ("notAllowed");
957 else
958 Read ();
959 RelaxngNotAllowed na = new RelaxngNotAllowed ();
960 FillLocation (na);
961 return na;
964 public override string ReadString ()
966 skipExternal = false;
967 string s = base.ReadString ();
968 skipExternal = true;
969 return s;