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