* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / Commons.Xml.Relaxng / Commons.Xml.Relaxng / RelaxngReader.cs
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
11 //
12
13 //
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.
32 //
33
34 using System;
35 using System.Collections;
36 using System.Xml;
37
38 namespace Commons.Xml.Relaxng
39 {
40         public class RelaxngReader : XmlDefaultReader
41         {
42                 // static members.
43                 static RelaxngPattern grammarForRelaxng;
44                 static XmlReader relaxngXmlReader;
45                 static RelaxngReader ()
46                 {
47                         relaxngXmlReader = new XmlTextReader (typeof (RelaxngReader).Assembly.GetManifestResourceStream ("relaxng.rng"));
48                         grammarForRelaxng =
49                                 RelaxngPattern.Read (relaxngXmlReader);
50                 }
51
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; }
56                 }
57
58
59                 // fields
60                 Stack nsStack = new Stack ();
61                 Stack datatypeLibraryStack = new Stack ();
62                 XmlResolver resolver;
63 //              ArrayList annotationNamespaces = new ArrayList ();
64
65                 // ctor
66                 public RelaxngReader (XmlReader reader)
67                         : this (reader, null)
68                 {
69                 }
70
71                 public RelaxngReader (XmlReader reader, string ns)
72                         : this (reader, ns, new XmlUrlResolver ())
73                 {
74                 }
75
76                 public RelaxngReader (XmlReader reader, string ns, XmlResolver resolver)
77 //                      : base (grammarForRelaxng == null ? reader : new RelaxngValidatingReader (reader, grammarForRelaxng))
78                         : base (reader)
79                 {
80                         this.resolver = resolver;
81                         if (Reader.ReadState == ReadState.Initial)
82                                 Read ();
83                         MoveToContent ();
84                         string nsval = GetSpaceStrippedAttribute ("ns", String.Empty);
85                         if (nsval == null)
86                                 nsval = ns;
87                         nsStack.Push (nsval == null ? String.Empty : nsval);
88                         string dtlib = GetSpaceStrippedAttribute ("datatypeLibrary", String.Empty);
89                         datatypeLibraryStack.Push (dtlib != null ?
90                                 dtlib : String.Empty);
91                 }
92
93                 public XmlResolver XmlResolver {
94                         set { resolver = value; }
95                 }
96
97                 internal XmlResolver Resolver {
98                         get { return resolver; }
99                 }
100
101                 private void FillLocation (RelaxngElementBase el)
102                 {
103                         el.BaseUri = BaseURI;
104                         IXmlLineInfo li = this as IXmlLineInfo;
105                         el.LineNumber = li != null ? li.LineNumber : 0;
106                         el.LinePosition = li != null ? li.LinePosition : 0;
107                 }
108
109 /*
110                 public void AddAnnotationNamespace (string ns)
111                 {
112                         if (!annotationNamespaces.Contains (ns))
113                                 annotationNamespaces.Add (ns);
114                 }
115 */
116
117                 // public
118                 public override bool Read ()
119                 {
120                         bool skipRead = false;
121                         bool b = false;
122                         bool loop = true;
123                         if (IsEmptyElement) { // this should be done here
124                                 nsStack.Pop ();
125                                 datatypeLibraryStack.Pop ();
126                         }
127                         do {
128                                 if (!skipRead)
129                                         Reader.Read ();
130                                 else
131                                         skipRead = false;
132                                 switch (NodeType) {
133                                 case XmlNodeType.ProcessingInstruction:
134                                 case XmlNodeType.Comment:
135                                 case XmlNodeType.EntityReference:
136                                         continue;
137                                 case XmlNodeType.Whitespace:
138                                 // Skip whitespaces except for data and param.
139                                 case XmlNodeType.SignificantWhitespace:
140                                         if (LocalName != "value" && LocalName != "param") {
141                                                 continue;
142                                         }
143                                         else
144                                                 loop = false;
145                                         break;
146                                 default:
147                                         if (NamespaceURI != RelaxngGrammar.NamespaceURI) {
148                                                 Reader.Skip ();
149                                                 skipRead = true;
150                                         }
151                                         else
152                                                 loop = false;
153                                         break;
154                                 }
155                         } while (!Reader.EOF && loop);
156
157                         switch (NodeType) {
158                         case XmlNodeType.Element:
159                                 if (MoveToAttribute ("ns")) {
160                                         nsStack.Push (Value.Trim ());
161                                         MoveToElement ();
162                                 }
163                                 else
164                                         nsStack.Push (ContextNamespace);
165
166                                 if (MoveToAttribute ("datatypeLibrary")) {
167                                         string uriString = Value.Trim ();
168                                         if (uriString.Length == 0)
169                                                 datatypeLibraryStack.Push (String.Empty);
170                                         else {
171                                                 try {
172                                                         Uri uri = new Uri (uriString);
173                                                         // MS.NET Uri is too lamespec
174                                                         datatypeLibraryStack.Push (uri.ToString ());
175                                                 } catch (UriFormatException ex) {
176                                                         throw new RelaxngException (ex.Message, ex);
177                                                 }
178                                         }
179                                         MoveToElement ();
180                                 }
181                                 else
182                                         datatypeLibraryStack.Push (DatatypeLibrary);
183                                 break;
184
185                         case XmlNodeType.EndElement:
186                                 nsStack.Pop ();
187                                 datatypeLibraryStack.Pop ();
188                                 break;
189                         }
190
191                         return b;
192                 }
193
194                 // Properties
195
196                 public string ContextNamespace {
197                         get {
198                                 if (nsStack.Count == 0)
199                                         // It happens only on initialization.
200                                         return String.Empty;
201                                 return nsStack.Peek () as string;
202                         }
203                 }
204
205                 public string DatatypeLibrary {
206                         get {
207                                 if (datatypeLibraryStack.Count == 0)
208                                         // It happens only on initialization.
209                                         return String.Empty;
210                                 return datatypeLibraryStack.Peek () as string;
211                         }
212                 }
213
214                 // Utility methods.
215                 private void expect (string name)
216                 {
217                         if (NamespaceURI != RelaxngGrammar.NamespaceURI)
218                                 throw new RelaxngException (String.Format ("Invalid document: expected namespace {0} but found {1}", RelaxngGrammar.NamespaceURI, NamespaceURI));
219                         else if (LocalName != name)
220                                 throw new RelaxngException (String.Format ("Invalid document: expected local name {0} but found {1}", name, LocalName));
221                 }
222
223                 private void expectEnd (string name)
224                 {
225                         if (NodeType != XmlNodeType.EndElement)
226                                 throw new RelaxngException (String.Format ("Expected EndElement but found {0}.", NodeType));
227                         expect (name);
228
229                         Read ();
230                 }
231
232                 // Other than name class and pattern.
233                 private RelaxngStart ReadStart ()
234                 {
235                         RelaxngStart s = new RelaxngStart ();
236                         FillLocation (s);
237                         expect ("start");
238
239                         if (MoveToFirstAttribute ()) {
240                                 do {
241                                         if (NamespaceURI != String.Empty)
242                                                 continue;
243                                         switch (LocalName) {
244                                         case "datatypeLibrary":
245                                         case  "combine":
246                                                 break;
247                                         default:
248                                                 throw new RelaxngException ("Invalid attribute.");
249                                         }
250                                 } while (MoveToNextAttribute ());
251                                 MoveToElement ();
252                         }
253
254                         if (MoveToAttribute ("combine")) {
255                                 s.Combine = Value.Trim ();
256                                 if (s.Combine != "choice" && s.Combine != "interleave")
257                                         throw new RelaxngException ("Invalid combine attribute: " + s.Combine);
258                         }
259
260                         MoveToElement ();
261                         Read ();
262                         s.Pattern = ReadPattern ();
263                         expectEnd ("start");
264                         return s;
265                 }
266
267                 private string GetNameAttribute ()
268                 {
269                         string name = GetSpaceStrippedAttribute ("name", String.Empty);
270                         if (name == null)
271                                 throw new RelaxngException ("Required attribute name is not found.");
272                         return XmlConvert.VerifyNCName (name);
273                 }
274
275                 private string GetSpaceStrippedAttribute (string name, string ns)
276                 {
277                         string v = GetAttribute (name, ns);
278                         return v != null ? v.Trim () : null;
279                 }
280
281                 private RelaxngDefine ReadDefine ()
282                 {
283                         RelaxngDefine def = new RelaxngDefine ();
284                         FillLocation (def);
285                         expect ("define");
286                         def.Name = GetNameAttribute ();
287                         def.Combine = GetSpaceStrippedAttribute ("combine", String.Empty);
288
289                         Read ();
290                         while (NodeType == XmlNodeType.Element)
291                                 def.Patterns.Add (ReadPattern ());
292                         expectEnd ("define");
293                         return def;
294                 }
295
296                 private RelaxngParam ReadParam ()
297                 {
298                         RelaxngParam p = new RelaxngParam ();
299                         FillLocation (p);
300                         expect ("param");
301                         p.Name = GetNameAttribute ();
302                         p.Value = ReadString ().Trim ();
303                         expectEnd ("param");
304                         return p;
305                 }
306
307                 // NameClass reader (only if it is element-style.)
308                 private RelaxngNameClass ReadNameClass ()
309                 {
310                         switch (LocalName) {
311                         case "name":
312                                 return ReadNameClassName ();
313                         case "anyName":
314                                 return ReadNameClassAnyName ();
315                         case "nsName":
316                                 return ReadNameClassNsName ();
317                         case "choice":
318                                 return ReadNameClassChoice ();
319                         }
320                         throw new RelaxngException ("Invalid name class: " + LocalName);
321                 }
322
323                 private RelaxngName ReadNameClassName ()
324                 {
325                         string name = ReadString ().Trim ();
326                         RelaxngName rName = resolvedName (name);
327                         expectEnd ("name");
328                         return rName;
329                 }
330
331                 private RelaxngAnyName ReadNameClassAnyName ()
332                 {
333                         RelaxngAnyName an = new RelaxngAnyName ();
334                         FillLocation (an);
335                         if (!IsEmptyElement) {
336                                 Read ();
337                                 if (NodeType == XmlNodeType.EndElement) {
338                                 } else {
339                                         // expect except
340                                         expect ("except");
341                                         Read ();
342                                         an.Except = new RelaxngExceptNameClass ();
343                                         FillLocation (an.Except);
344                                         while (NodeType == XmlNodeType.Element)
345                                                 an.Except.Names.Add (
346                                                         ReadNameClass ());
347                                         expectEnd ("except");
348                                 }
349                                 expectEnd ("anyName");
350                         } else
351                                 Read ();
352                         return an;
353                 }
354
355                 private RelaxngNsName ReadNameClassNsName ()
356                 {
357                         RelaxngNsName nn = new RelaxngNsName ();
358                         FillLocation (nn);
359                         nn.Namespace = this.ContextNamespace;
360                         if (!IsEmptyElement) {
361                                 Read ();
362                                 if (NodeType == XmlNodeType.EndElement) {
363                                 } else {
364                                         // expect except
365                                         expect ("except");
366 //                                      Read ();
367                                         nn.Except = ReadNameClassExcept ();//new RelaxngExceptNameClass ();
368                                         FillLocation (nn.Except);
369                                 }
370                                 expectEnd ("nsName");
371                         } else
372                                 Read ();
373                         return nn;
374                 }
375
376                 private RelaxngNameChoice ReadNameClassChoice ()
377                 {
378                         RelaxngNameChoice nc = new RelaxngNameChoice ();
379                         FillLocation (nc);
380                         if (IsEmptyElement)
381                                 throw new RelaxngException ("Name choice must have at least one name class.");
382
383                         Read ();
384                         while (NodeType != XmlNodeType.EndElement) {
385                                 nc.Children.Add (ReadNameClass ());
386                         }
387                         if (nc.Children.Count == 0)
388                                 throw new RelaxngException ("Name choice must have at least one name class.");
389
390                         expectEnd ("choice");
391                         return nc;
392                 }
393
394                 private RelaxngExceptNameClass ReadNameClassExcept ()
395                 {
396                         RelaxngExceptNameClass x = new RelaxngExceptNameClass ();
397                         FillLocation (x);
398                         if (IsEmptyElement)
399                                 throw new RelaxngException ("Name choice must have at least one name class.");
400
401                         Read ();
402                         while (NodeType != XmlNodeType.EndElement)
403                                 x.Names.Add (ReadNameClass ());
404                         if (x.Names.Count == 0)
405                                 throw new RelaxngException ("Name choice must have at least one name class.");
406
407                         expectEnd ("except");
408                         return x;
409                 }
410
411                 // Pattern reader
412
413                 public RelaxngPattern ReadPattern ()
414                 {
415                         while (NodeType != XmlNodeType.Element)
416                                 if (!Read ())
417                                         throw new RelaxngException ("RELAX NG pattern did not appear.");
418
419                         switch (LocalName) {
420                         case "element":
421                                 return ReadElementPattern ();
422                         case "attribute":
423                                 return ReadAttributePattern ();
424                         case "group":
425                                 return ReadGroupPattern ();
426                         case "interleave":
427                                 return ReadInterleavePattern ();
428                         case "choice":
429                                 return ReadChoicePattern ();
430                         case "optional":
431                                 return ReadOptionalPattern ();
432                         case "zeroOrMore":
433                                 return ReadZeroOrMorePattern ();
434                         case "oneOrMore":
435                                 return ReadOneOrMorePattern ();
436                         case "list":
437                                 return ReadListPattern ();
438                         case "mixed":
439                                 return ReadMixedPattern ();
440                         case "ref":
441                                 return ReadRefPattern ();
442                         case "parentRef":
443                                 return ReadParentRefPattern ();
444                         case "empty":
445                                 return ReadEmptyPattern ();
446                         case "text":
447                                 return ReadTextPattern ();
448                         case "data":
449                                 return ReadDataPattern ();
450                         case "value":
451                                 return ReadValuePattern ();
452                         case "notAllowed":
453                                 return ReadNotAllowedPattern ();
454                         case "externalRef":
455                                 return ReadExternalRefPattern ();
456                         case "grammar":
457                                 return ReadGrammarPattern ();
458                         }
459                         throw new RelaxngException ("Non-supported pattern specification: " + LocalName);
460                 }
461
462                 private void ReadPatterns (RelaxngSingleContentPattern el)
463                 {
464                         do {
465                                 el.Patterns.Add (ReadPattern ());
466                         } while (NodeType == XmlNodeType.Element);
467                 }
468
469                 private void ReadPatterns (RelaxngBinaryContentPattern el)
470                 {
471                         do {
472                                 el.Patterns.Add (ReadPattern ());
473                         } while (NodeType == XmlNodeType.Element);
474                 }
475
476                 private RelaxngExcept ReadPatternExcept ()
477                 {
478                         RelaxngExcept x = new RelaxngExcept ();
479                         FillLocation (x);
480                         if (IsEmptyElement)
481                                 throw new RelaxngException ("'except' must have at least one pattern.");
482                         Read ();
483                         while (NodeType != XmlNodeType.EndElement)
484                                 x.Patterns.Add (ReadPattern ());
485                         if (x.Patterns.Count == 0)
486                                 throw new RelaxngException ("'except' must have at least one pattern.");
487
488                         expectEnd ("except");
489                         return x;
490                 }
491
492                 private RelaxngInclude ReadInclude ()
493                 {
494                         RelaxngInclude i = new RelaxngInclude ();
495                         FillLocation (i);
496                         expect ("include");
497                         i.NSContext = ContextNamespace;
498                         string href = GetSpaceStrippedAttribute ("href", String.Empty);
499                         if (href == null)
500                                 throw new RelaxngException ("Required attribute href was not found.");
501                         XmlResolver res = resolver != null ? resolver : new XmlUrlResolver ();
502                         i.Href = res.ResolveUri (BaseURI != null ? new Uri (BaseURI) : null, href).AbsoluteUri;
503                         if (!IsEmptyElement) {
504                                 Read ();
505                                 this.readGrammarIncludeContent (i.Starts, i.Defines, i.Divs, null);
506                                 expectEnd ("include");
507                         }
508                         else
509                                 Read ();
510                         return i;
511                 }
512
513                 private void readGrammarIncludeContent (IList starts, IList defines, IList divs, IList includes)
514                 {
515                         while (NodeType == XmlNodeType.Element) {
516                                 switch (LocalName) {
517                                 case "start":
518                                         starts.Add (ReadStart ());
519                                         break;
520                                 case "define":
521                                         defines.Add (ReadDefine ());
522                                         break;
523                                 case "div":
524                                         divs.Add (ReadDiv (includes != null));
525                                         break;
526                                 case "include":
527                                         if (includes != null)
528                                                 includes.Add (ReadInclude ());
529                                         else
530                                                 throw new RelaxngException ("Unexpected content: " + Name);
531                                         break;
532                                 default:
533                                         throw new RelaxngException ("Unexpected content: " + Name);
534                                 }
535                         }
536                 }
537
538                 private RelaxngDiv ReadDiv (bool allowIncludes)
539                 {
540                         expect ("div");
541                         RelaxngDiv div = new RelaxngDiv ();
542                         FillLocation (div);
543                         if (!IsEmptyElement) {
544                                 Read ();
545                                 readGrammarIncludeContent (div.Starts, div.Defines, div.Divs, div.Includes);
546                                 expectEnd ("div");
547                         }
548                         else
549                                 Read ();
550                         return div;
551                 }
552
553                 private RelaxngName resolvedName (string nameSpec)
554                 {
555                         int colonAt = nameSpec.IndexOf (':');
556                         string prefix = (colonAt < 0) ? "" : nameSpec.Substring (0, colonAt);
557                         string local = (colonAt < 0) ? nameSpec : nameSpec.Substring (colonAt + 1, nameSpec.Length - colonAt - 1);
558                         string uri = ContextNamespace;
559
560                         if (prefix != "") {
561                                 uri = LookupNamespace (prefix);
562                                 if (uri == null)
563                                         throw new RelaxngException ("Undeclared prefix in name component: " + nameSpec);
564                         }
565                         RelaxngName n = new RelaxngName (local, uri);
566                         FillLocation (n);
567                         return n;
568                 }
569
570                 private RelaxngElement ReadElementPattern ()
571                 {
572                         RelaxngElement el = new RelaxngElement ();
573                         FillLocation (el);
574
575                         if (MoveToFirstAttribute ()) {
576                                 do {
577                                         if (NamespaceURI != String.Empty)
578                                                 continue;
579                                         switch (LocalName) {
580                                         case "datatypeLibrary":
581                                         case  "name":
582                                         case "ns":
583                                                 break;
584                                         default:
585                                                 throw new RelaxngException ("Invalid attribute.");
586                                         }
587                                 } while (MoveToNextAttribute ());
588                                 MoveToElement ();
589                         }
590
591                         // try to get name from attribute.
592                         if (MoveToAttribute ("name"))
593                                 el.NameClass = resolvedName (XmlConvert.VerifyName (Value.Trim ()));
594                         MoveToElement ();
595                         Read ();
596
597                         // read nameClass from content.
598                         if (el.NameClass == null)
599                                 el.NameClass = ReadNameClass ();
600
601                         // read patterns.
602                         this.ReadPatterns (el);
603
604                         expectEnd ("element");
605
606                         if (el.NameClass == null)
607                                 throw new RelaxngException ("Name class was not specified.");
608                         return el;
609                 }
610
611                 private RelaxngAttribute ReadAttributePattern ()
612                 {
613                         RelaxngAttribute attr = new RelaxngAttribute ();
614                         FillLocation (attr);
615
616                         if (MoveToFirstAttribute ()) {
617                                 do {
618                                         if (NamespaceURI != String.Empty)
619                                                 continue;
620                                         switch (LocalName) {
621                                         case "datatypeLibrary":
622                                         case "name":
623                                         case "ns":
624                                                 break;
625                                         default:
626                                                 throw new RelaxngException ("Invalid attribute.");
627                                         }
628                                 } while (MoveToNextAttribute ());
629                                 MoveToElement ();
630                         }
631
632                         string ns = GetSpaceStrippedAttribute ("ns", String.Empty);
633
634                         // try to get name from attribute.
635                         if (MoveToAttribute ("name", String.Empty)) {
636 //                              attr.NameClass = resolvedName (XmlConvert.VerifyName (Value.Trim ()), false);
637                                 RelaxngName nc = new RelaxngName ();
638                                 string name = XmlConvert.VerifyName (Value.Trim ());
639                                 if (name.IndexOf (':') > 0)
640                                         nc = resolvedName (name);
641                                 else {
642                                         nc.LocalName = name;
643                                         nc.Namespace = ns == null ? String.Empty : ns;
644                                 }
645                                 attr.NameClass = nc;
646                         }
647
648                         MoveToElement ();
649                         if (!IsEmptyElement) {
650                                 Read ();
651                                 // read nameClass from content.
652                                 if (attr.NameClass == null)
653                                         attr.NameClass = ReadNameClass ();
654
655                                 if (NodeType == XmlNodeType.Element)
656                                         attr.Pattern = ReadPattern ();
657
658                                 expectEnd ("attribute");
659                         } else
660                                 Read ();
661
662                         if (attr.NameClass == null)
663                                 throw new RelaxngException ("Name class was not specified.");
664                         return attr;
665                 }
666
667                 private RelaxngGrammar ReadGrammarPattern ()
668                 {
669                         RelaxngGrammar grammar = new RelaxngGrammar ();
670                         FillLocation (grammar);
671                         grammar.DefaultNamespace = Reader.GetAttribute ("ns");
672                         Read ();
673                         this.readGrammarIncludeContent (grammar.Starts, grammar.Defines, grammar.Divs, grammar.Includes);
674                         expectEnd ("grammar");
675
676                         return grammar;
677                 }
678
679                 private RelaxngRef ReadRefPattern ()
680                 {
681                         RelaxngRef r = new RelaxngRef ();
682                         FillLocation (r);
683                         expect ("ref");
684                         r.Name = GetNameAttribute ();
685                         if (!IsEmptyElement) {
686                                 Read ();
687                                 expectEnd ("ref");
688                         }
689                         else
690                                 Read ();
691                         return r;
692                 }
693
694                 private RelaxngExternalRef ReadExternalRefPattern ()
695                 {
696                         RelaxngExternalRef r = new RelaxngExternalRef ();
697                         FillLocation (r);
698                         expect ("externalRef");
699                         string href = GetSpaceStrippedAttribute ("href", String.Empty);
700                         if (href == null)
701                                 throw new RelaxngException ("Required attribute href was not found.");
702                         XmlResolver res = resolver != null ? resolver : new XmlUrlResolver ();
703                         r.Href = res.ResolveUri (BaseURI != null ? new Uri (BaseURI) : null, href).AbsoluteUri;
704                         r.NSContext = ContextNamespace;
705                         if (!IsEmptyElement) {
706                                 Read ();
707                                 expectEnd ("externalRef");
708                         }
709                         else
710                                 Read ();
711                         return r;
712                 }
713
714                 private RelaxngParentRef ReadParentRefPattern ()
715                 {
716                         RelaxngParentRef r = new RelaxngParentRef ();
717                         FillLocation (r);
718                         expect ("parentRef");
719                         r.Name = GetNameAttribute ();
720                         if (!IsEmptyElement) {
721                                 Read ();
722                                 expectEnd ("parentRef");
723                         }
724                         else
725                                 Read ();
726                         return r;
727                 }
728
729                 private RelaxngEmpty ReadEmptyPattern ()
730                 {
731                         expect ("empty");
732
733                         if (MoveToFirstAttribute ()) {
734                                 do {
735                                         if (NamespaceURI == String.Empty && LocalName != "datatypeLibrary")
736                                                 throw new RelaxngException ("Invalid attribute.");
737                                 } while (MoveToNextAttribute ());
738                                 MoveToElement ();
739                         }
740
741                         if (!IsEmptyElement) {
742                                 Read ();
743                                 expectEnd ("empty");
744                         }
745                         else
746                                 Read ();
747
748                         RelaxngEmpty empty = new RelaxngEmpty ();
749                         FillLocation (empty);
750                         return empty;
751                 }
752
753                 private RelaxngText ReadTextPattern ()
754                 {
755                         expect ("text");
756
757                         if (MoveToFirstAttribute ()) {
758                                 do {
759                                         if (NamespaceURI == String.Empty && LocalName != "datatypeLibrary")
760                                                 throw new RelaxngException ("Invalid attribute.");
761                                 } while (MoveToNextAttribute ());
762                                 MoveToElement ();
763                         }
764
765                         if (!IsEmptyElement) {
766                                 Read ();
767                                 expectEnd ("text");
768                         }
769                         else
770                                 Read ();
771
772                         RelaxngText t = new RelaxngText ();
773                         FillLocation (t);
774                         return t;
775                 }
776
777                 private RelaxngData ReadDataPattern ()
778                 {
779                         RelaxngData data = new RelaxngData ();
780                         FillLocation (data);
781
782                         expect ("data");
783                         data.Type = GetSpaceStrippedAttribute ("type", String.Empty);
784                         if (data.Type == null)
785                                 throw new RelaxngException ("Attribute type is required.");
786                         data.DatatypeLibrary = DatatypeLibrary;
787
788                         if (MoveToFirstAttribute ()) {
789                                 do {
790                                         if (NamespaceURI != String.Empty)
791                                                 continue;
792                                         switch (LocalName) {
793                                         case "datatypeLibrary":
794                                         case "type":
795                                                 break;
796                                         default:
797                                                 throw new RelaxngException ("Invalid attribute.");
798                                         }
799                                 } while (MoveToNextAttribute ());
800                                 MoveToElement ();
801                         }
802
803                         if (!IsEmptyElement) {
804                                 Read ();
805                                 while (Name == "param") {
806                                         data.ParamList.Add (ReadParam ());
807                                 }
808                                 if (LocalName == "except")
809                                         data.Except = ReadPatternExcept ();
810                                 expectEnd ("data");
811                         } else
812                                 Read ();
813
814                         return data;
815                 }
816
817                 private RelaxngValue ReadValuePattern ()
818                 {
819                         RelaxngValue v = new RelaxngValue ();
820                         FillLocation (v);
821                         expect ("value");
822
823                         if (MoveToFirstAttribute ()) {
824                                 do {
825                                         if (NamespaceURI != String.Empty)
826                                                 continue;
827                                         switch (LocalName) {
828                                         case "datatypeLibrary":
829                                         case "type":
830                                         case "ns":
831                                                 break;
832                                         default:
833                                                 throw new RelaxngException ("Invalid attribute.");
834                                         }
835                                 } while (MoveToNextAttribute ());
836                                 MoveToElement ();
837                         }
838
839                         if (MoveToAttribute ("type")) {
840                                 v.Type = Value.Trim ();
841                                 v.DatatypeLibrary = DatatypeLibrary;
842                         } else {
843                                 v.Type = "token";
844                                 v.DatatypeLibrary = "";
845                         }
846 //                      v.Namespace = GetSpaceStrippedAttribute ("ns", String.Empty);
847                         MoveToElement ();
848                         if (IsEmptyElement) {
849                                 v.Value = String.Empty;
850                                 Read ();
851                         } else {
852                                 v.Value = ReadString ();
853                                 expectEnd ("value");
854                         }
855
856                         return v;
857                 }
858
859                 private RelaxngList ReadListPattern ()
860                 {
861                         RelaxngList list = new RelaxngList ();
862                         FillLocation (list);
863                         expect ("list");
864                         Read ();
865                         ReadPatterns (list);
866                         expectEnd ("list");
867                         return list;
868                 }
869
870                 private RelaxngOneOrMore ReadOneOrMorePattern ()
871                 {
872                         RelaxngOneOrMore o = new RelaxngOneOrMore ();
873                         FillLocation (o);
874                         expect ("oneOrMore");
875                         Read ();
876                         ReadPatterns (o);
877                         expectEnd ("oneOrMore");
878                         return o;
879                 }
880
881                 private RelaxngZeroOrMore ReadZeroOrMorePattern ()
882                 {
883                         RelaxngZeroOrMore o = new RelaxngZeroOrMore ();
884                         FillLocation (o);
885                         expect ("zeroOrMore");
886                         Read ();
887                         ReadPatterns (o);
888                         expectEnd ("zeroOrMore");
889                         return o;
890                 }
891
892                 private RelaxngOptional ReadOptionalPattern ()
893                 {
894                         RelaxngOptional o = new RelaxngOptional ();
895                         FillLocation (o);
896                         expect ("optional");
897                         Read ();
898                         ReadPatterns (o);
899                         expectEnd ("optional");
900                         return o;
901                 }
902
903                 private RelaxngMixed ReadMixedPattern ()
904                 {
905                         RelaxngMixed o = new RelaxngMixed ();
906                         FillLocation (o);
907                         expect ("mixed");
908                         Read ();
909                         ReadPatterns (o);
910                         expectEnd ("mixed");
911                         return o;
912                 }
913
914                 private RelaxngGroup ReadGroupPattern ()
915                 {
916                         RelaxngGroup g = new RelaxngGroup ();
917                         FillLocation (g);
918                         expect ("group");
919                         Read ();
920                         ReadPatterns (g);
921                         expectEnd ("group");
922                         return g;
923                 }
924
925                 private RelaxngInterleave ReadInterleavePattern ()
926                 {
927                         RelaxngInterleave i = new RelaxngInterleave ();
928                         FillLocation (i);
929                         expect ("interleave");
930                         Read ();
931                         ReadPatterns (i);
932                         expectEnd ("interleave");
933                         return i;
934                 }
935
936                 private RelaxngChoice ReadChoicePattern ()
937                 {
938                         RelaxngChoice c = new RelaxngChoice ();
939                         FillLocation (c);
940                         expect ("choice");
941                         Read ();
942                         ReadPatterns (c);
943                         expectEnd ("choice");
944                         return c;
945                 }
946
947                 private RelaxngNotAllowed ReadNotAllowedPattern ()
948                 {
949                         expect ("notAllowed");
950                         if (!IsEmptyElement) {
951                                 Read ();
952                                 expectEnd ("notAllowed");
953                         }
954                         else
955                                 Read ();
956                         RelaxngNotAllowed na = new RelaxngNotAllowed ();
957                         FillLocation (na);
958                         return na;
959                 }
960         }
961 }