New test.
[mono.git] / mcs / class / Commons.Xml.Relaxng / Commons.Xml.Relaxng / RelaxngReader.cs
index 04250f1923a27b9b61e55b54788d03daaa6da9f9..fbb040893cdb6ec3dfecb88671433a113e528faf 100644 (file)
-//\r
-// Commons.Xml.Relaxng.RelaxngReader.cs\r
-//\r
-// Author:\r
-//     Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>\r
-//\r
-// 2003 Atsushi Enomoto "No rights reserved."\r
-//\r
-\r
-using System;\r
-using System.Collections;\r
-using System.Xml;\r
-\r
-namespace Commons.Xml.Relaxng\r
-{\r
-       public class RelaxngReader : XmlDefaultReader\r
-       {\r
-               // static members.\r
-               static RelaxngPattern relaxngGrammar;\r
-               static XmlReader relaxngXmlReader;\r
-               static RelaxngReader ()\r
-               {\r
-//                     relaxngXmlReader = new XmlTextReader ("relaxng.rng");\r
-//                     relaxngGrammar = RelaxngPattern.Read (relaxngXmlReader);\r
-               }\r
-\r
-               public static string RelaxngNS = "http://relaxng.org/ns/structure/1.0";\r
-//             public static RelaxngPattern RelaxngGrammar {\r
-//                     get { return relaxngGrammar; }\r
-//             }\r
-\r
-\r
-               // fields\r
-               Stack nsStack = new Stack ();\r
-               Stack datatypeLibraryStack = new Stack ();\r
-               XmlResolver resolver = new XmlUrlResolver ();\r
-\r
-               // ctor\r
-               public RelaxngReader (XmlReader reader)\r
-                       : this (reader, null)\r
-               {\r
-               }\r
-\r
-               public RelaxngReader (XmlReader reader, string ns)\r
-//                     : base (reader == relaxngXmlReader ? reader : new RelaxngValidatingReader (reader, relaxngGrammar))\r
-                       : base (reader)\r
-               {\r
-                       nsStack.Push (ns == null ? "" : ns);\r
-                       datatypeLibraryStack.Push ("");\r
-\r
-                       if (Reader.ReadState == ReadState.Initial)\r
-                               Read ();\r
-                       MoveToContent ();\r
-               }\r
-\r
-               public XmlResolver XmlResolver {\r
-                       set { resolver = value; }\r
-               }\r
-\r
-               internal XmlResolver Resolver {\r
-                       get { return resolver; }\r
-               }\r
-\r
-               private void FillLocation (RelaxngElementBase el)\r
-               {\r
-                       el.BaseUri = BaseURI;\r
-                       IXmlLineInfo li = this as IXmlLineInfo;\r
-                       el.LineNumber = li != null ? li.LineNumber : 0;\r
-                       el.LinePosition = li != null ? li.LinePosition : 0;\r
-               }\r
-\r
-               // public\r
-               public override bool Read ()\r
-               {\r
-                       bool skipRead = false;\r
-                       bool b = false;\r
-                       bool loop = true;\r
-                       if (IsEmptyElement) { // this should be done here\r
-                               nsStack.Pop ();\r
-                               datatypeLibraryStack.Pop ();\r
-                       }\r
-                       do {\r
-                               if (!skipRead)\r
-                                       b = Reader.Read ();\r
-                               else\r
-                                       skipRead = false;\r
-                               switch (NodeType) {\r
-                               case XmlNodeType.ProcessingInstruction:\r
-                               case XmlNodeType.Comment:\r
-                               case XmlNodeType.EntityReference:\r
-                                       continue;\r
-                               case XmlNodeType.Whitespace:\r
-                               // Skip whitespaces except for data and param.\r
-                               case XmlNodeType.SignificantWhitespace:\r
-                                       if (LocalName != "value" && LocalName != "param") {\r
-                                               continue;\r
-                                       }\r
-                                       else\r
-                                               loop = false;\r
-                                       break;\r
-                               default:\r
-                                       if (NamespaceURI != RelaxngNS) {\r
-                                               Reader.Skip ();\r
-                                               skipRead = true;\r
-                                       }\r
-                                       else\r
-                                               loop = false;\r
-                                       break;\r
-                               }\r
-                       } while (b && loop);\r
-\r
-                       switch (NodeType) {\r
-                       case XmlNodeType.Element:\r
-                               if (MoveToAttribute ("ns"))\r
-                                       nsStack.Push (Value.Trim ());\r
-                               else\r
-                                       nsStack.Push (nsStack.Peek ());\r
-\r
-                               if (MoveToAttribute ("datatypeLibrary")) {\r
-                                       string uriString = Value.Trim ();\r
-                                       if (uriString.Length == 0)\r
-                                               datatypeLibraryStack.Push (String.Empty);\r
-                                       else {\r
-                                               try {\r
-                                                       Uri uri = new Uri (uriString);\r
-                                                       // MS.NET Uri is too lamespec\r
-                                                       datatypeLibraryStack.Push (uri.ToString ());\r
-                                               } catch (UriFormatException ex) {\r
-                                                       throw new RelaxngException (ex.Message, ex);\r
-                                               }\r
-                                       }\r
-                               }\r
-                               else\r
-                                       datatypeLibraryStack.Push (datatypeLibraryStack.Peek ());\r
-                               MoveToElement ();\r
-                               break;\r
-\r
-                       case XmlNodeType.EndElement:\r
-                               nsStack.Pop ();\r
-                               datatypeLibraryStack.Pop ();\r
-                               break;\r
-                       }\r
-\r
-                       return b;\r
-               }\r
-\r
-               // Properties\r
-\r
-               public string ContextNamespace {\r
-                       get { return nsStack.Peek () as string; }\r
-               }\r
-\r
-               public string DatatypeLibrary {\r
-                       get { return datatypeLibraryStack.Peek () as string; }\r
-               }\r
-\r
-               // Utility methods.\r
-               private void expect (string name)\r
-               {\r
-                       if (NamespaceURI != RelaxngGrammar.NamespaceURI)\r
-                               throw new RelaxngException (String.Format ("Invalid document: expected namespace {0} but found {1}", RelaxngGrammar.NamespaceURI, NamespaceURI));\r
-                       else if (LocalName != name)\r
-                               throw new RelaxngException (String.Format ("Invalid document: expected local name {0} but found {1}", name, LocalName));\r
-               }\r
-\r
-               private void expectEnd (string name)\r
-               {\r
-                       if (NodeType != XmlNodeType.EndElement)\r
-                               throw new RelaxngException (String.Format ("Expected EndElement but found {0}.", NodeType));\r
-                       expect (name);\r
-\r
-                       Read ();\r
-               }\r
-\r
-               // Other than name class and pattern.\r
-               private RelaxngStart ReadStart ()\r
-               {\r
-                       RelaxngStart s = new RelaxngStart ();\r
-                       FillLocation (s);\r
-                       expect ("start");\r
-\r
-                       if (MoveToFirstAttribute ()) {\r
-                               do {\r
-                                       if (NamespaceURI != String.Empty)\r
-                                               continue;\r
-                                       switch (LocalName) {\r
-                                       case "datatypeLibrary":\r
-                                       case  "combine":\r
-                                               break;\r
-                                       default:\r
-                                               throw new RelaxngException ("Invalid attribute.");\r
-                                       }\r
-                               } while (MoveToNextAttribute ());\r
-                               MoveToElement ();\r
-                       }\r
-\r
-                       if (MoveToAttribute ("combine")) {\r
-                               s.Combine = Value.Trim ();\r
-                               if (s.Combine != "choice" && s.Combine != "interleave")\r
-                                       throw new RelaxngException ("Invalid combine attribute: " + s.Combine);\r
-                       }\r
-\r
-                       MoveToElement ();\r
-                       Read ();\r
-                       s.Pattern = ReadPattern ();\r
-                       expectEnd ("start");\r
-                       return s;\r
-               }\r
-\r
-               private string GetNameAttribute ()\r
-               {\r
-                       string name = GetSpaceStrippedAttribute ("name");\r
-                       if (name == null)\r
-                               throw new RelaxngException ("Required attribute name is not found.");\r
-                       return XmlConvert.VerifyNCName (name);\r
-               }\r
-\r
-               private string GetSpaceStrippedAttribute (string name)\r
-               {\r
-                       string v = GetAttribute (name);\r
-                       return v != null ? v.Trim () : null;\r
-               }\r
-\r
-               private RelaxngDefine ReadDefine ()\r
-               {\r
-                       RelaxngDefine def = new RelaxngDefine ();\r
-                       FillLocation (def);\r
-                       expect ("define");\r
-                       def.Name = GetNameAttribute ();\r
-                       def.Combine = GetSpaceStrippedAttribute ("combine");\r
-\r
-                       Read ();\r
-                       while (NodeType == XmlNodeType.Element)\r
-                               def.Patterns.Add (ReadPattern ());\r
-                       expectEnd ("define");\r
-                       return def;\r
-               }\r
-\r
-               private RelaxngParam ReadParam ()\r
-               {\r
-                       RelaxngParam p = new RelaxngParam ();\r
-                       FillLocation (p);\r
-                       expect ("param");\r
-                       p.Name = GetNameAttribute ();\r
-                       p.Value = ReadString ().Trim ();\r
-                       expectEnd ("param");\r
-                       return p;\r
-               }\r
-\r
-               // NameClass reader (only if it is element-style.)\r
-               private RelaxngNameClass ReadNameClass ()\r
-               {\r
-                       switch (LocalName) {\r
-                       case "name":\r
-                               return ReadNameClassName ();\r
-                       case "anyName":\r
-                               return ReadNameClassAnyName ();\r
-                       case "nsName":\r
-                               return ReadNameClassNsName ();\r
-                       case "choice":\r
-                               return ReadNameClassChoice ();\r
-                       }\r
-                       throw new RelaxngException ("Invalid name class: " + LocalName);\r
-               }\r
-\r
-               private RelaxngName ReadNameClassName ()\r
-               {\r
-                       string name = ReadString ().Trim ();\r
-                       RelaxngName rName = resolvedName (name);\r
-                       expectEnd ("name");\r
-                       return rName;\r
-               }\r
-\r
-               private RelaxngAnyName ReadNameClassAnyName ()\r
-               {\r
-                       RelaxngAnyName an = new RelaxngAnyName ();\r
-                       FillLocation (an);\r
-                       if (!IsEmptyElement) {\r
-                               Read ();\r
-                               if (NodeType == XmlNodeType.EndElement) {\r
-                               } else {\r
-                                       // expect except\r
-                                       expect ("except");\r
-                                       Read ();\r
-                                       an.Except = new RelaxngExceptNameClass ();\r
-                                       FillLocation (an.Except);\r
-                                       while (NodeType == XmlNodeType.Element)\r
-                                               an.Except.Names.Add (\r
-                                                       ReadNameClass ());\r
-                                       expectEnd ("except");\r
-                               }\r
-                               expectEnd ("anyName");\r
-                       } else\r
-                               Read ();\r
-                       return an;\r
-               }\r
-\r
-               private RelaxngNsName ReadNameClassNsName ()\r
-               {\r
-                       RelaxngNsName nn = new RelaxngNsName ();\r
-                       FillLocation (nn);\r
-                       nn.Namespace = this.ContextNamespace;\r
-                       if (!IsEmptyElement) {\r
-                               Read ();\r
-                               if (NodeType == XmlNodeType.EndElement) {\r
-                               } else {\r
-                                       // expect except\r
-                                       expect ("except");\r
-//                                     Read ();\r
-                                       nn.Except = ReadNameClassExcept ();//new RelaxngExceptNameClass ();\r
-                                       FillLocation (nn.Except);\r
-                               }\r
-                               expectEnd ("nsName");\r
-                       } else\r
-                               Read ();\r
-                       return nn;\r
-               }\r
-\r
-               private RelaxngNameChoice ReadNameClassChoice ()\r
-               {\r
-                       RelaxngNameChoice nc = new RelaxngNameChoice ();\r
-                       FillLocation (nc);\r
-                       if (IsEmptyElement)\r
-                               throw new RelaxngException ("Name choice must have at least one name class.");\r
-\r
-                       Read ();\r
-                       while (NodeType != XmlNodeType.EndElement) {\r
-                               nc.Children.Add (ReadNameClass ());\r
-                       }\r
-                       if (nc.Children.Count == 0)\r
-                               throw new RelaxngException ("Name choice must have at least one name class.");\r
-\r
-                       expectEnd ("choice");\r
-                       return nc;\r
-               }\r
-\r
-               private RelaxngExceptNameClass ReadNameClassExcept ()\r
-               {\r
-                       RelaxngExceptNameClass x = new RelaxngExceptNameClass ();\r
-                       FillLocation (x);\r
-                       if (IsEmptyElement)\r
-                               throw new RelaxngException ("Name choice must have at least one name class.");\r
-\r
-                       Read ();\r
-                       while (NodeType != XmlNodeType.EndElement)\r
-                               x.Names.Add (ReadNameClass ());\r
-                       if (x.Names.Count == 0)\r
-                               throw new RelaxngException ("Name choice must have at least one name class.");\r
-\r
-                       expectEnd ("except");\r
-                       return x;\r
-               }\r
-\r
-               // Pattern reader\r
-\r
-               public RelaxngPattern ReadPattern ()\r
-               {\r
-                       while (NodeType != XmlNodeType.Element)\r
-                               if (!Read ())\r
-                                       break;\r
-\r
-                       switch (LocalName) {\r
-                       case "element":\r
-                               return ReadElementPattern ();\r
-                       case "attribute":\r
-                               return ReadAttributePattern ();\r
-                       case "group":\r
-                               return ReadGroupPattern ();\r
-                       case "interleave":\r
-                               return ReadInterleavePattern ();\r
-                       case "choice":\r
-                               return ReadChoicePattern ();\r
-                       case "optional":\r
-                               return ReadOptionalPattern ();\r
-                       case "zeroOrMore":\r
-                               return ReadZeroOrMorePattern ();\r
-                       case "oneOrMore":\r
-                               return ReadOneOrMorePattern ();\r
-                       case "list":\r
-                               return ReadListPattern ();\r
-                       case "mixed":\r
-                               return ReadMixedPattern ();\r
-                       case "ref":\r
-                               return ReadRefPattern ();\r
-                       case "parentRef":\r
-                               return ReadParentRefPattern ();\r
-                       case "empty":\r
-                               return ReadEmptyPattern ();\r
-                       case "text":\r
-                               return ReadTextPattern ();\r
-                       case "data":\r
-                               return ReadDataPattern ();\r
-                       case "value":\r
-                               return ReadValuePattern ();\r
-                       case "notAllowed":\r
-                               return ReadNotAllowedPattern ();\r
-                       case "externalRef":\r
-                               return ReadExternalRefPattern ();\r
-                       case "grammar":\r
-                               return ReadGrammarPattern ();\r
-                       }\r
-                       throw new RelaxngException ("Non-supported pattern specification: " + LocalName);\r
-               }\r
-\r
-               private void ReadPatterns (RelaxngSingleContentPattern el)\r
-               {\r
-                       do {\r
-                               el.Patterns.Add (ReadPattern ());\r
-                       } while (NodeType == XmlNodeType.Element);\r
-               }\r
-\r
-               private void ReadPatterns (RelaxngBinaryContentPattern el)\r
-               {\r
-                       do {\r
-                               el.Patterns.Add (ReadPattern ());\r
-                       } while (NodeType == XmlNodeType.Element);\r
-               }\r
-\r
-               private RelaxngExcept ReadPatternExcept ()\r
-               {\r
-                       RelaxngExcept x = new RelaxngExcept ();\r
-                       FillLocation (x);\r
-                       if (IsEmptyElement)\r
-                               throw new RelaxngException ("'except' must have at least one pattern.");\r
-                       Read ();\r
-                       while (NodeType != XmlNodeType.EndElement)\r
-                               x.Patterns.Add (ReadPattern ());\r
-                       if (x.Patterns.Count == 0)\r
-                               throw new RelaxngException ("'except' must have at least one pattern.");\r
-\r
-                       expectEnd ("except");\r
-                       return x;\r
-               }\r
-\r
-               private RelaxngInclude ReadInclude ()\r
-               {\r
-                       RelaxngInclude i = new RelaxngInclude ();\r
-                       FillLocation (i);\r
-                       expect ("include");\r
-                       i.NSContext = ContextNamespace;\r
-                       string href = GetSpaceStrippedAttribute ("href");\r
-                       if (href == null)\r
-                               throw new RelaxngException ("Required attribute href was not found.");\r
-                       i.Href = Util.ResolveUri (BaseURI, href, resolver);\r
-                       if (!IsEmptyElement) {\r
-                               Read ();\r
-                               this.readGrammarIncludeContent (i.Starts, i.Defines, i.Divs, null);\r
-                               expectEnd ("include");\r
-                       }\r
-                       else\r
-                               Read ();\r
-                       return i;\r
-               }\r
-\r
-               private void readGrammarIncludeContent (IList starts, IList defines, IList divs, IList includes)\r
-               {\r
-                       while (NodeType == XmlNodeType.Element) {\r
-                               switch (LocalName) {\r
-                               case "start":\r
-                                       starts.Add (ReadStart ());\r
-                                       break;\r
-                               case "define":\r
-                                       defines.Add (ReadDefine ());\r
-                                       break;\r
-                               case "div":\r
-                                       divs.Add (ReadDiv (includes != null));\r
-                                       break;\r
-                               case "include":\r
-                                       if (includes != null)\r
-                                               includes.Add (ReadInclude ());\r
-                                       else\r
-                                               throw new RelaxngException ("Unexpected content: " + Name);\r
-                                       break;\r
-                               default:\r
-                                       throw new RelaxngException ("Unexpected content: " + Name);\r
-                               }\r
-                       }\r
-               }\r
-\r
-               private RelaxngDiv ReadDiv (bool allowIncludes)\r
-               {\r
-                       expect ("div");\r
-                       RelaxngDiv div = new RelaxngDiv ();\r
-                       FillLocation (div);\r
-                       if (!IsEmptyElement) {\r
-                               Read ();\r
-                               readGrammarIncludeContent (div.Starts, div.Defines, div.Divs, div.Includes);\r
-                               expectEnd ("div");\r
-                       }\r
-                       else\r
-                               Read ();\r
-                       return div;\r
-               }\r
-\r
-               private RelaxngName resolvedName (string nameSpec)\r
-               {\r
-                       int colonAt = nameSpec.IndexOf (':');\r
-                       string prefix = (colonAt < 0) ? "" : nameSpec.Substring (0, colonAt);\r
-                       string local = (colonAt < 0) ? nameSpec : nameSpec.Substring (colonAt + 1, nameSpec.Length - colonAt - 1);\r
-                       string uri = ContextNamespace;\r
-\r
-                       if (prefix != "") {\r
-                               uri = LookupNamespace (prefix);\r
-                               if (uri == null)\r
-                                       throw new RelaxngException ("Undeclared prefix in name component: " + nameSpec);\r
-                       }\r
-                       RelaxngName n = new RelaxngName (local, uri);\r
-                       FillLocation (n);\r
-                       return n;\r
-               }\r
-\r
-               private RelaxngElement ReadElementPattern ()\r
-               {\r
-                       RelaxngElement el = new RelaxngElement ();\r
-                       FillLocation (el);\r
-\r
-                       if (MoveToFirstAttribute ()) {\r
-                               do {\r
-                                       if (NamespaceURI != String.Empty)\r
-                                               continue;\r
-                                       switch (LocalName) {\r
-                                       case "datatypeLibrary":\r
-                                       case  "name":\r
-                                       case "ns":\r
-                                               break;\r
-                                       default:\r
-                                               throw new RelaxngException ("Invalid attribute.");\r
-                                       }\r
-                               } while (MoveToNextAttribute ());\r
-                               MoveToElement ();\r
-                       }\r
-\r
-                       // try to get name from attribute.\r
-                       if (MoveToAttribute ("name"))\r
-                               el.NameClass = resolvedName (XmlConvert.VerifyName (Value.Trim ()));\r
-                       MoveToElement ();\r
-                       Read ();\r
-\r
-                       // read nameClass from content.\r
-                       if (el.NameClass == null)\r
-                               el.NameClass = ReadNameClass ();\r
-\r
-                       // read patterns.\r
-                       this.ReadPatterns (el);\r
-\r
-                       expectEnd ("element");\r
-\r
-                       if (el.NameClass == null)\r
-                               throw new RelaxngException ("Name class was not specified.");\r
-                       return el;\r
-               }\r
-\r
-               private RelaxngAttribute ReadAttributePattern ()\r
-               {\r
-                       RelaxngAttribute attr = new RelaxngAttribute ();\r
-                       FillLocation (attr);\r
-\r
-                       if (MoveToFirstAttribute ()) {\r
-                               do {\r
-                                       if (NamespaceURI != String.Empty)\r
-                                               continue;\r
-                                       switch (LocalName) {\r
-                                       case "datatypeLibrary":\r
-                                       case  "name":\r
-                                       case "ns":\r
-                                               break;\r
-                                       default:\r
-                                               throw new RelaxngException ("Invalid attribute.");\r
-                                       }\r
-                               } while (MoveToNextAttribute ());\r
-                               MoveToElement ();\r
-                       }\r
-\r
-                       string ns = GetSpaceStrippedAttribute ("ns");\r
-\r
-                       // try to get name from attribute.\r
-                       if (MoveToAttribute ("name")) {\r
-//                             attr.NameClass = resolvedName (XmlConvert.VerifyName (Value.Trim ()), false);\r
-                               RelaxngName nc = new RelaxngName ();\r
-                               string name = XmlConvert.VerifyName (Value.Trim ());\r
-                               if (name.IndexOf (':') > 0)\r
-                                       nc = resolvedName (name);\r
-                               else {\r
-                                       nc.LocalName = name;\r
-                                       nc.Namespace = ns == null ? String.Empty : ns;\r
-                               }\r
-                               attr.NameClass = nc;\r
-                       }\r
-\r
-                       MoveToElement ();\r
-                       if (!IsEmptyElement) {\r
-                               Read ();\r
-                               // read nameClass from content.\r
-                               if (attr.NameClass == null)\r
-                                       attr.NameClass = ReadNameClass ();\r
-\r
-                               if (NodeType == XmlNodeType.Element)\r
-                                       attr.Pattern = ReadPattern ();\r
-\r
-                               expectEnd ("attribute");\r
-                       } else\r
-                               Read ();\r
-\r
-                       if (attr.NameClass == null)\r
-                               throw new RelaxngException ("Name class was not specified.");\r
-                       return attr;\r
-               }\r
-\r
-               private RelaxngGrammar ReadGrammarPattern ()\r
-               {\r
-                       RelaxngGrammar grammar = new RelaxngGrammar ();\r
-                       FillLocation (grammar);\r
-                       Read ();\r
-                       this.readGrammarIncludeContent (grammar.Starts, grammar.Defines, grammar.Divs, grammar.Includes);\r
-                       expectEnd ("grammar");\r
-\r
-                       return grammar;\r
-               }\r
-\r
-               private RelaxngRef ReadRefPattern ()\r
-               {\r
-                       RelaxngRef r = new RelaxngRef ();\r
-                       FillLocation (r);\r
-                       expect ("ref");\r
-                       r.Name = GetNameAttribute ();\r
-                       if (!IsEmptyElement) {\r
-                               Read ();\r
-                               expectEnd ("ref");\r
-                       }\r
-                       else\r
-                               Read ();\r
-                       return r;\r
-               }\r
-\r
-               private RelaxngExternalRef ReadExternalRefPattern ()\r
-               {\r
-                       RelaxngExternalRef r = new RelaxngExternalRef ();\r
-                       FillLocation (r);\r
-                       expect ("externalRef");\r
-                       string href = GetSpaceStrippedAttribute ("href");\r
-                       if (href == null)\r
-                               throw new RelaxngException ("Required attribute href was not found.");\r
-                       r.Href = Util.ResolveUri (BaseURI, href, resolver);\r
-                       r.NSContext = ContextNamespace;\r
-                       if (!IsEmptyElement) {\r
-                               Read ();\r
-                               expectEnd ("externalRef");\r
-                       }\r
-                       else\r
-                               Read ();\r
-                       return r;\r
-               }\r
-\r
-               private RelaxngParentRef ReadParentRefPattern ()\r
-               {\r
-                       RelaxngParentRef r = new RelaxngParentRef ();\r
-                       FillLocation (r);\r
-                       expect ("parentRef");\r
-                       r.Name = GetNameAttribute ();\r
-                       if (!IsEmptyElement) {\r
-                               Read ();\r
-                               expectEnd ("parentRef");\r
-                       }\r
-                       else\r
-                               Read ();\r
-                       return r;\r
-               }\r
-\r
-               private RelaxngEmpty ReadEmptyPattern ()\r
-               {\r
-                       expect ("empty");\r
-\r
-                       if (MoveToFirstAttribute ()) {\r
-                               do {\r
-                                       if (NamespaceURI == String.Empty && LocalName != "datatypeLibrary")\r
-                                               throw new RelaxngException ("Invalid attribute.");\r
-                               } while (MoveToNextAttribute ());\r
-                               MoveToElement ();\r
-                       }\r
-\r
-                       if (!IsEmptyElement) {\r
-                               Read ();\r
-                               expectEnd ("empty");\r
-                       }\r
-                       else\r
-                               Read ();\r
-\r
-                       RelaxngEmpty empty = new RelaxngEmpty ();\r
-                       FillLocation (empty);\r
-                       return empty;\r
-               }\r
-\r
-               private RelaxngText ReadTextPattern ()\r
-               {\r
-                       expect ("text");\r
-\r
-                       if (MoveToFirstAttribute ()) {\r
-                               do {\r
-                                       if (NamespaceURI == String.Empty && LocalName != "datatypeLibrary")\r
-                                               throw new RelaxngException ("Invalid attribute.");\r
-                               } while (MoveToNextAttribute ());\r
-                               MoveToElement ();\r
-                       }\r
-\r
-                       if (!IsEmptyElement) {\r
-                               Read ();\r
-                               expectEnd ("text");\r
-                       }\r
-                       else\r
-                               Read ();\r
-\r
-                       RelaxngText t = new RelaxngText ();\r
-                       FillLocation (t);\r
-                       return t;\r
-               }\r
-\r
-               private RelaxngData ReadDataPattern ()\r
-               {\r
-                       RelaxngData data = new RelaxngData ();\r
-                       FillLocation (data);\r
-\r
-                       expect ("data");\r
-                       data.Type = GetSpaceStrippedAttribute ("type");\r
-                       if (data.Type == null)\r
-                               throw new RelaxngException ("Attribute type is required.");\r
-                       data.DatatypeLibrary = DatatypeLibrary;\r
-\r
-                       if (MoveToFirstAttribute ()) {\r
-                               do {\r
-                                       if (NamespaceURI != String.Empty)\r
-                                               continue;\r
-                                       switch (LocalName) {\r
-                                       case "datatypeLibrary":\r
-                                       case "type":\r
-                                               break;\r
-                                       default:\r
-                                               throw new RelaxngException ("Invalid attribute.");\r
-                                       }\r
-                               } while (MoveToNextAttribute ());\r
-                               MoveToElement ();\r
-                       }\r
-\r
-                       if (!IsEmptyElement) {\r
-                               Read ();\r
-                               while (Name == "param") {\r
-                                       data.ParamList.Add (ReadParam ());\r
-                               }\r
-                               if (LocalName == "except")\r
-                                       data.Except = ReadPatternExcept ();\r
-                               expectEnd ("data");\r
-                       } else\r
-                               Read ();\r
-\r
-                       return data;\r
-               }\r
-\r
-               private RelaxngValue ReadValuePattern ()\r
-               {\r
-                       RelaxngValue v = new RelaxngValue ();\r
-                       FillLocation (v);\r
-                       expect ("value");\r
-\r
-                       if (MoveToFirstAttribute ()) {\r
-                               do {\r
-                                       if (NamespaceURI != String.Empty)\r
-                                               continue;\r
-                                       switch (LocalName) {\r
-                                       case "datatypeLibrary":\r
-                                       case "type":\r
-                                       case "ns":\r
-                                               break;\r
-                                       default:\r
-                                               throw new RelaxngException ("Invalid attribute.");\r
-                                       }\r
-                               } while (MoveToNextAttribute ());\r
-                               MoveToElement ();\r
-                       }\r
-\r
-                       if (MoveToAttribute ("type")) {\r
-                               v.Type = Value.Trim ();\r
-                               v.DatatypeLibrary = DatatypeLibrary;\r
-                       } else {\r
-                               v.Type = "token";\r
-                               v.DatatypeLibrary = "";\r
-                       }\r
-//                     v.Namespace = GetSpaceStrippedAttribute ("ns");\r
-                       MoveToElement ();\r
-                       if (IsEmptyElement) {\r
-                               v.Value = String.Empty;\r
-                               Read ();\r
-                       } else {\r
-                               v.Value = ReadString ();\r
-                               expectEnd ("value");\r
-                       }\r
-\r
-                       return v;\r
-               }\r
-\r
-               private RelaxngList ReadListPattern ()\r
-               {\r
-                       RelaxngList list = new RelaxngList ();\r
-                       FillLocation (list);\r
-                       expect ("list");\r
-                       Read ();\r
-                       ReadPatterns (list);\r
-                       expectEnd ("list");\r
-                       return list;\r
-               }\r
-\r
-               private RelaxngOneOrMore ReadOneOrMorePattern ()\r
-               {\r
-                       RelaxngOneOrMore o = new RelaxngOneOrMore ();\r
-                       FillLocation (o);\r
-                       expect ("oneOrMore");\r
-                       Read ();\r
-                       ReadPatterns (o);\r
-                       expectEnd ("oneOrMore");\r
-                       return o;\r
-               }\r
-\r
-               private RelaxngZeroOrMore ReadZeroOrMorePattern ()\r
-               {\r
-                       RelaxngZeroOrMore o = new RelaxngZeroOrMore ();\r
-                       FillLocation (o);\r
-                       expect ("zeroOrMore");\r
-                       Read ();\r
-                       ReadPatterns (o);\r
-                       expectEnd ("zeroOrMore");\r
-                       return o;\r
-               }\r
-\r
-               private RelaxngOptional ReadOptionalPattern ()\r
-               {\r
-                       RelaxngOptional o = new RelaxngOptional ();\r
-                       FillLocation (o);\r
-                       expect ("optional");\r
-                       Read ();\r
-                       ReadPatterns (o);\r
-                       expectEnd ("optional");\r
-                       return o;\r
-               }\r
-\r
-               private RelaxngMixed ReadMixedPattern ()\r
-               {\r
-                       RelaxngMixed o = new RelaxngMixed ();\r
-                       FillLocation (o);\r
-                       expect ("mixed");\r
-                       Read ();\r
-                       ReadPatterns (o);\r
-                       expectEnd ("mixed");\r
-                       return o;\r
-               }\r
-\r
-               private RelaxngGroup ReadGroupPattern ()\r
-               {\r
-                       RelaxngGroup g = new RelaxngGroup ();\r
-                       FillLocation (g);\r
-                       expect ("group");\r
-                       Read ();\r
-                       ReadPatterns (g);\r
-                       expectEnd ("group");\r
-                       return g;\r
-               }\r
-\r
-               private RelaxngInterleave ReadInterleavePattern ()\r
-               {\r
-                       RelaxngInterleave i = new RelaxngInterleave ();\r
-                       FillLocation (i);\r
-                       expect ("interleave");\r
-                       Read ();\r
-                       ReadPatterns (i);\r
-                       expectEnd ("interleave");\r
-                       return i;\r
-               }\r
-\r
-               private RelaxngChoice ReadChoicePattern ()\r
-               {\r
-                       RelaxngChoice c = new RelaxngChoice ();\r
-                       FillLocation (c);\r
-                       expect ("choice");\r
-                       Read ();\r
-                       ReadPatterns (c);\r
-                       expectEnd ("choice");\r
-                       return c;\r
-               }\r
-\r
-               private RelaxngNotAllowed ReadNotAllowedPattern ()\r
-               {\r
-                       expect ("notAllowed");\r
-                       if (!IsEmptyElement) {\r
-                               Read ();\r
-                               expectEnd ("notAllowed");\r
-                       }\r
-                       else\r
-                               Read ();\r
-                       RelaxngNotAllowed na = new RelaxngNotAllowed ();\r
-                       FillLocation (na);\r
-                       return na;\r
-               }\r
-       }\r
+//
+// Commons.Xml.Relaxng.RelaxngReader.cs
+//
+// Author:
+//     Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
+//
+// 2003 Atsushi Enomoto "No rights reserved."
+//
+// Copyright (c) 2004 Novell Inc.
+// All rights reserved
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.Xml;
+
+namespace Commons.Xml.Relaxng
+{
+       public class RelaxngReader : XmlDefaultReader
+       {
+               // static members.
+               static RelaxngPattern grammarForRelaxng;
+               static XmlReader relaxngXmlReader;
+               static RelaxngReader ()
+               {
+                       relaxngXmlReader = new XmlTextReader (typeof (RelaxngReader).Assembly.GetManifestResourceStream ("relaxng.rng"));
+                       grammarForRelaxng =
+                               RelaxngPattern.Read (relaxngXmlReader);
+               }
+
+               [Obsolete] // incorrectly introduced
+               public static string RelaxngNS = "http://relaxng.org/ns/structure/1.0";
+               public static RelaxngPattern GrammarForRelaxng {
+                       get { return grammarForRelaxng; }
+               }
+
+
+               // fields
+               Stack nsStack = new Stack ();
+               Stack datatypeLibraryStack = new Stack ();
+               XmlResolver resolver;
+//             ArrayList annotationNamespaces = new ArrayList ();
+
+               // ctor
+               public RelaxngReader (XmlReader reader)
+                       : this (reader, null)
+               {
+               }
+
+               public RelaxngReader (XmlReader reader, string ns)
+                       : this (reader, ns, new XmlUrlResolver ())
+               {
+               }
+
+               public RelaxngReader (XmlReader reader, string ns, XmlResolver resolver)
+//                     : base (grammarForRelaxng == null ? reader : new RelaxngValidatingReader (reader, grammarForRelaxng))
+                       : base (reader)
+               {
+                       this.resolver = resolver;
+                       if (Reader.ReadState == ReadState.Initial)
+                               Read ();
+                       MoveToContent ();
+                       string nsval = GetSpaceStrippedAttribute ("ns", String.Empty);
+                       if (nsval == null)
+                               nsval = ns;
+                       nsStack.Push (nsval == null ? String.Empty : nsval);
+                       string dtlib = GetSpaceStrippedAttribute ("datatypeLibrary", String.Empty);
+                       datatypeLibraryStack.Push (dtlib != null ?
+                               dtlib : String.Empty);
+               }
+
+               public XmlResolver XmlResolver {
+                       set { resolver = value; }
+               }
+
+               internal XmlResolver Resolver {
+                       get { return resolver; }
+               }
+
+               private void FillLocation (RelaxngElementBase el)
+               {
+                       el.BaseUri = BaseURI;
+                       IXmlLineInfo li = this as IXmlLineInfo;
+                       el.LineNumber = li != null ? li.LineNumber : 0;
+                       el.LinePosition = li != null ? li.LinePosition : 0;
+               }
+
+/*
+               public void AddAnnotationNamespace (string ns)
+               {
+                       if (!annotationNamespaces.Contains (ns))
+                               annotationNamespaces.Add (ns);
+               }
+*/
+
+               // public
+               public override bool Read ()
+               {
+                       bool skipRead = false;
+                       bool b = false;
+                       bool loop = true;
+                       if (IsEmptyElement) { // this should be done here
+                               nsStack.Pop ();
+                               datatypeLibraryStack.Pop ();
+                       }
+                       do {
+                               if (!skipRead)
+                                       Reader.Read ();
+                               else
+                                       skipRead = false;
+                               switch (NodeType) {
+                               case XmlNodeType.ProcessingInstruction:
+                               case XmlNodeType.Comment:
+                               case XmlNodeType.EntityReference:
+                                       continue;
+                               case XmlNodeType.Whitespace:
+                               // Skip whitespaces except for data and param.
+                               case XmlNodeType.SignificantWhitespace:
+                                       if (LocalName != "value" && LocalName != "param") {
+                                               continue;
+                                       }
+                                       else
+                                               loop = false;
+                                       break;
+                               default:
+                                       if (NamespaceURI != RelaxngGrammar.NamespaceURI) {
+                                               Reader.Skip ();
+                                               skipRead = true;
+                                       }
+                                       else
+                                               loop = false;
+                                       break;
+                               }
+                       } while (!Reader.EOF && loop);
+
+                       switch (NodeType) {
+                       case XmlNodeType.Element:
+                               if (MoveToAttribute ("ns")) {
+                                       nsStack.Push (Value.Trim ());
+                                       MoveToElement ();
+                               }
+                               else
+                                       nsStack.Push (ContextNamespace);
+
+                               if (MoveToAttribute ("datatypeLibrary")) {
+                                       string uriString = Value.Trim ();
+                                       if (uriString.Length == 0)
+                                               datatypeLibraryStack.Push (String.Empty);
+                                       else {
+                                               try {
+                                                       Uri uri = new Uri (uriString);
+                                                       // MS.NET Uri is too lamespec
+                                                       datatypeLibraryStack.Push (uri.ToString ());
+                                               } catch (UriFormatException ex) {
+                                                       throw new RelaxngException (ex.Message, ex);
+                                               }
+                                       }
+                                       MoveToElement ();
+                               }
+                               else
+                                       datatypeLibraryStack.Push (DatatypeLibrary);
+                               break;
+
+                       case XmlNodeType.EndElement:
+                               nsStack.Pop ();
+                               datatypeLibraryStack.Pop ();
+                               break;
+                       }
+
+                       return b;
+               }
+
+               // Properties
+
+               public string ContextNamespace {
+                       get {
+                               if (nsStack.Count == 0)
+                                       // It happens only on initialization.
+                                       return String.Empty;
+                               return nsStack.Peek () as string;
+                       }
+               }
+
+               public string DatatypeLibrary {
+                       get {
+                               if (datatypeLibraryStack.Count == 0)
+                                       // It happens only on initialization.
+                                       return String.Empty;
+                               return datatypeLibraryStack.Peek () as string;
+                       }
+               }
+
+               // Utility methods.
+               private void expect (string name)
+               {
+                       if (NamespaceURI != RelaxngGrammar.NamespaceURI)
+                               throw new RelaxngException (String.Format ("Invalid document: expected namespace {0} but found {1}", RelaxngGrammar.NamespaceURI, NamespaceURI));
+                       else if (LocalName != name)
+                               throw new RelaxngException (String.Format ("Invalid document: expected local name {0} but found {1}", name, LocalName));
+               }
+
+               private void expectEnd (string name)
+               {
+                       if (NodeType != XmlNodeType.EndElement)
+                               throw new RelaxngException (String.Format ("Expected EndElement but found {0}.", NodeType));
+                       expect (name);
+
+                       Read ();
+               }
+
+               // Other than name class and pattern.
+               private RelaxngStart ReadStart ()
+               {
+                       RelaxngStart s = new RelaxngStart ();
+                       FillLocation (s);
+                       expect ("start");
+
+                       if (MoveToFirstAttribute ()) {
+                               do {
+                                       if (NamespaceURI != String.Empty)
+                                               continue;
+                                       switch (LocalName) {
+                                       case "datatypeLibrary":
+                                       case  "combine":
+                                               break;
+                                       default:
+                                               throw new RelaxngException ("Invalid attribute.");
+                                       }
+                               } while (MoveToNextAttribute ());
+                               MoveToElement ();
+                       }
+
+                       if (MoveToAttribute ("combine")) {
+                               s.Combine = Value.Trim ();
+                               if (s.Combine != "choice" && s.Combine != "interleave")
+                                       throw new RelaxngException ("Invalid combine attribute: " + s.Combine);
+                       }
+
+                       MoveToElement ();
+                       Read ();
+                       s.Pattern = ReadPattern ();
+                       expectEnd ("start");
+                       return s;
+               }
+
+               private string GetNameAttribute ()
+               {
+                       string name = GetSpaceStrippedAttribute ("name", String.Empty);
+                       if (name == null)
+                               throw new RelaxngException ("Required attribute name is not found.");
+                       return XmlConvert.VerifyNCName (name);
+               }
+
+               private string GetSpaceStrippedAttribute (string name, string ns)
+               {
+                       string v = GetAttribute (name, ns);
+                       return v != null ? v.Trim () : null;
+               }
+
+               private RelaxngDefine ReadDefine ()
+               {
+                       RelaxngDefine def = new RelaxngDefine ();
+                       FillLocation (def);
+                       expect ("define");
+                       def.Name = GetNameAttribute ();
+                       def.Combine = GetSpaceStrippedAttribute ("combine", String.Empty);
+
+                       Read ();
+                       while (NodeType == XmlNodeType.Element)
+                               def.Patterns.Add (ReadPattern ());
+                       expectEnd ("define");
+                       return def;
+               }
+
+               private RelaxngParam ReadParam ()
+               {
+                       RelaxngParam p = new RelaxngParam ();
+                       FillLocation (p);
+                       expect ("param");
+                       p.Name = GetNameAttribute ();
+                       p.Value = ReadString ().Trim ();
+                       expectEnd ("param");
+                       return p;
+               }
+
+               // NameClass reader (only if it is element-style.)
+               private RelaxngNameClass ReadNameClass ()
+               {
+                       switch (LocalName) {
+                       case "name":
+                               return ReadNameClassName ();
+                       case "anyName":
+                               return ReadNameClassAnyName ();
+                       case "nsName":
+                               return ReadNameClassNsName ();
+                       case "choice":
+                               return ReadNameClassChoice ();
+                       }
+                       throw new RelaxngException ("Invalid name class: " + LocalName);
+               }
+
+               private RelaxngName ReadNameClassName ()
+               {
+                       string name = ReadString ().Trim ();
+                       RelaxngName rName = resolvedName (name);
+                       expectEnd ("name");
+                       return rName;
+               }
+
+               private RelaxngAnyName ReadNameClassAnyName ()
+               {
+                       RelaxngAnyName an = new RelaxngAnyName ();
+                       FillLocation (an);
+                       if (!IsEmptyElement) {
+                               Read ();
+                               if (NodeType == XmlNodeType.EndElement) {
+                               } else {
+                                       // expect except
+                                       expect ("except");
+                                       Read ();
+                                       an.Except = new RelaxngExceptNameClass ();
+                                       FillLocation (an.Except);
+                                       while (NodeType == XmlNodeType.Element)
+                                               an.Except.Names.Add (
+                                                       ReadNameClass ());
+                                       expectEnd ("except");
+                               }
+                               expectEnd ("anyName");
+                       } else
+                               Read ();
+                       return an;
+               }
+
+               private RelaxngNsName ReadNameClassNsName ()
+               {
+                       RelaxngNsName nn = new RelaxngNsName ();
+                       FillLocation (nn);
+                       nn.Namespace = this.ContextNamespace;
+                       if (!IsEmptyElement) {
+                               Read ();
+                               if (NodeType == XmlNodeType.EndElement) {
+                               } else {
+                                       // expect except
+                                       expect ("except");
+//                                     Read ();
+                                       nn.Except = ReadNameClassExcept ();//new RelaxngExceptNameClass ();
+                                       FillLocation (nn.Except);
+                               }
+                               expectEnd ("nsName");
+                       } else
+                               Read ();
+                       return nn;
+               }
+
+               private RelaxngNameChoice ReadNameClassChoice ()
+               {
+                       RelaxngNameChoice nc = new RelaxngNameChoice ();
+                       FillLocation (nc);
+                       if (IsEmptyElement)
+                               throw new RelaxngException ("Name choice must have at least one name class.");
+
+                       Read ();
+                       while (NodeType != XmlNodeType.EndElement) {
+                               nc.Children.Add (ReadNameClass ());
+                       }
+                       if (nc.Children.Count == 0)
+                               throw new RelaxngException ("Name choice must have at least one name class.");
+
+                       expectEnd ("choice");
+                       return nc;
+               }
+
+               private RelaxngExceptNameClass ReadNameClassExcept ()
+               {
+                       RelaxngExceptNameClass x = new RelaxngExceptNameClass ();
+                       FillLocation (x);
+                       if (IsEmptyElement)
+                               throw new RelaxngException ("Name choice must have at least one name class.");
+
+                       Read ();
+                       while (NodeType != XmlNodeType.EndElement)
+                               x.Names.Add (ReadNameClass ());
+                       if (x.Names.Count == 0)
+                               throw new RelaxngException ("Name choice must have at least one name class.");
+
+                       expectEnd ("except");
+                       return x;
+               }
+
+               // Pattern reader
+
+               public RelaxngPattern ReadPattern ()
+               {
+                       while (NodeType != XmlNodeType.Element)
+                               if (!Read ())
+                                       throw new RelaxngException ("RELAX NG pattern did not appear.");
+
+                       switch (LocalName) {
+                       case "element":
+                               return ReadElementPattern ();
+                       case "attribute":
+                               return ReadAttributePattern ();
+                       case "group":
+                               return ReadGroupPattern ();
+                       case "interleave":
+                               return ReadInterleavePattern ();
+                       case "choice":
+                               return ReadChoicePattern ();
+                       case "optional":
+                               return ReadOptionalPattern ();
+                       case "zeroOrMore":
+                               return ReadZeroOrMorePattern ();
+                       case "oneOrMore":
+                               return ReadOneOrMorePattern ();
+                       case "list":
+                               return ReadListPattern ();
+                       case "mixed":
+                               return ReadMixedPattern ();
+                       case "ref":
+                               return ReadRefPattern ();
+                       case "parentRef":
+                               return ReadParentRefPattern ();
+                       case "empty":
+                               return ReadEmptyPattern ();
+                       case "text":
+                               return ReadTextPattern ();
+                       case "data":
+                               return ReadDataPattern ();
+                       case "value":
+                               return ReadValuePattern ();
+                       case "notAllowed":
+                               return ReadNotAllowedPattern ();
+                       case "externalRef":
+                               return ReadExternalRefPattern ();
+                       case "grammar":
+                               return ReadGrammarPattern ();
+                       }
+                       throw new RelaxngException ("Non-supported pattern specification: " + LocalName);
+               }
+
+               private void ReadPatterns (RelaxngSingleContentPattern el)
+               {
+                       do {
+                               el.Patterns.Add (ReadPattern ());
+                       } while (NodeType == XmlNodeType.Element);
+               }
+
+               private void ReadPatterns (RelaxngBinaryContentPattern el)
+               {
+                       do {
+                               el.Patterns.Add (ReadPattern ());
+                       } while (NodeType == XmlNodeType.Element);
+               }
+
+               private RelaxngExcept ReadPatternExcept ()
+               {
+                       RelaxngExcept x = new RelaxngExcept ();
+                       FillLocation (x);
+                       if (IsEmptyElement)
+                               throw new RelaxngException ("'except' must have at least one pattern.");
+                       Read ();
+                       while (NodeType != XmlNodeType.EndElement)
+                               x.Patterns.Add (ReadPattern ());
+                       if (x.Patterns.Count == 0)
+                               throw new RelaxngException ("'except' must have at least one pattern.");
+
+                       expectEnd ("except");
+                       return x;
+               }
+
+               private RelaxngInclude ReadInclude ()
+               {
+                       RelaxngInclude i = new RelaxngInclude ();
+                       FillLocation (i);
+                       expect ("include");
+                       i.NSContext = ContextNamespace;
+                       string href = GetSpaceStrippedAttribute ("href", String.Empty);
+                       if (href == null)
+                               throw new RelaxngException ("Required attribute href was not found.");
+                       XmlResolver res = resolver != null ? resolver : new XmlUrlResolver ();
+                       i.Href = res.ResolveUri (BaseURI != null ? new Uri (BaseURI) : null, href).AbsoluteUri;
+                       if (!IsEmptyElement) {
+                               Read ();
+                               this.readGrammarIncludeContent (i.Starts, i.Defines, i.Divs, null);
+                               expectEnd ("include");
+                       }
+                       else
+                               Read ();
+                       return i;
+               }
+
+               private void readGrammarIncludeContent (IList starts, IList defines, IList divs, IList includes)
+               {
+                       while (NodeType == XmlNodeType.Element) {
+                               switch (LocalName) {
+                               case "start":
+                                       starts.Add (ReadStart ());
+                                       break;
+                               case "define":
+                                       defines.Add (ReadDefine ());
+                                       break;
+                               case "div":
+                                       divs.Add (ReadDiv (includes != null));
+                                       break;
+                               case "include":
+                                       if (includes != null)
+                                               includes.Add (ReadInclude ());
+                                       else
+                                               throw new RelaxngException ("Unexpected content: " + Name);
+                                       break;
+                               default:
+                                       throw new RelaxngException ("Unexpected content: " + Name);
+                               }
+                       }
+               }
+
+               private RelaxngDiv ReadDiv (bool allowIncludes)
+               {
+                       expect ("div");
+                       RelaxngDiv div = new RelaxngDiv ();
+                       FillLocation (div);
+                       if (!IsEmptyElement) {
+                               Read ();
+                               readGrammarIncludeContent (div.Starts, div.Defines, div.Divs, div.Includes);
+                               expectEnd ("div");
+                       }
+                       else
+                               Read ();
+                       return div;
+               }
+
+               private RelaxngName resolvedName (string nameSpec)
+               {
+                       int colonAt = nameSpec.IndexOf (':');
+                       string prefix = (colonAt < 0) ? "" : nameSpec.Substring (0, colonAt);
+                       string local = (colonAt < 0) ? nameSpec : nameSpec.Substring (colonAt + 1, nameSpec.Length - colonAt - 1);
+                       string uri = ContextNamespace;
+
+                       if (prefix != "") {
+                               uri = LookupNamespace (prefix);
+                               if (uri == null)
+                                       throw new RelaxngException ("Undeclared prefix in name component: " + nameSpec);
+                       }
+                       RelaxngName n = new RelaxngName (local, uri);
+                       FillLocation (n);
+                       return n;
+               }
+
+               private RelaxngElement ReadElementPattern ()
+               {
+                       RelaxngElement el = new RelaxngElement ();
+                       FillLocation (el);
+
+                       if (MoveToFirstAttribute ()) {
+                               do {
+                                       if (NamespaceURI != String.Empty)
+                                               continue;
+                                       switch (LocalName) {
+                                       case "datatypeLibrary":
+                                       case  "name":
+                                       case "ns":
+                                               break;
+                                       default:
+                                               throw new RelaxngException ("Invalid attribute.");
+                                       }
+                               } while (MoveToNextAttribute ());
+                               MoveToElement ();
+                       }
+
+                       // try to get name from attribute.
+                       if (MoveToAttribute ("name"))
+                               el.NameClass = resolvedName (XmlConvert.VerifyName (Value.Trim ()));
+                       MoveToElement ();
+                       Read ();
+
+                       // read nameClass from content.
+                       if (el.NameClass == null)
+                               el.NameClass = ReadNameClass ();
+
+                       // read patterns.
+                       this.ReadPatterns (el);
+
+                       expectEnd ("element");
+
+                       if (el.NameClass == null)
+                               throw new RelaxngException ("Name class was not specified.");
+                       return el;
+               }
+
+               private RelaxngAttribute ReadAttributePattern ()
+               {
+                       RelaxngAttribute attr = new RelaxngAttribute ();
+                       FillLocation (attr);
+
+                       if (MoveToFirstAttribute ()) {
+                               do {
+                                       if (NamespaceURI != String.Empty)
+                                               continue;
+                                       switch (LocalName) {
+                                       case "datatypeLibrary":
+                                       case "name":
+                                       case "ns":
+                                               break;
+                                       default:
+                                               throw new RelaxngException ("Invalid attribute.");
+                                       }
+                               } while (MoveToNextAttribute ());
+                               MoveToElement ();
+                       }
+
+                       string ns = GetSpaceStrippedAttribute ("ns", String.Empty);
+
+                       // try to get name from attribute.
+                       if (MoveToAttribute ("name", String.Empty)) {
+//                             attr.NameClass = resolvedName (XmlConvert.VerifyName (Value.Trim ()), false);
+                               RelaxngName nc = new RelaxngName ();
+                               string name = XmlConvert.VerifyName (Value.Trim ());
+                               if (name.IndexOf (':') > 0)
+                                       nc = resolvedName (name);
+                               else {
+                                       nc.LocalName = name;
+                                       nc.Namespace = ns == null ? String.Empty : ns;
+                               }
+                               attr.NameClass = nc;
+                       }
+
+                       MoveToElement ();
+                       if (!IsEmptyElement) {
+                               Read ();
+                               // read nameClass from content.
+                               if (attr.NameClass == null)
+                                       attr.NameClass = ReadNameClass ();
+
+                               if (NodeType == XmlNodeType.Element)
+                                       attr.Pattern = ReadPattern ();
+
+                               expectEnd ("attribute");
+                       } else
+                               Read ();
+
+                       if (attr.NameClass == null)
+                               throw new RelaxngException ("Name class was not specified.");
+                       return attr;
+               }
+
+               private RelaxngGrammar ReadGrammarPattern ()
+               {
+                       RelaxngGrammar grammar = new RelaxngGrammar ();
+                       FillLocation (grammar);
+                       grammar.DefaultNamespace = Reader.GetAttribute ("ns");
+                       Read ();
+                       this.readGrammarIncludeContent (grammar.Starts, grammar.Defines, grammar.Divs, grammar.Includes);
+                       expectEnd ("grammar");
+
+                       return grammar;
+               }
+
+               private RelaxngRef ReadRefPattern ()
+               {
+                       RelaxngRef r = new RelaxngRef ();
+                       FillLocation (r);
+                       expect ("ref");
+                       r.Name = GetNameAttribute ();
+                       if (!IsEmptyElement) {
+                               Read ();
+                               expectEnd ("ref");
+                       }
+                       else
+                               Read ();
+                       return r;
+               }
+
+               private RelaxngExternalRef ReadExternalRefPattern ()
+               {
+                       RelaxngExternalRef r = new RelaxngExternalRef ();
+                       FillLocation (r);
+                       expect ("externalRef");
+                       string href = GetSpaceStrippedAttribute ("href", String.Empty);
+                       if (href == null)
+                               throw new RelaxngException ("Required attribute href was not found.");
+                       XmlResolver res = resolver != null ? resolver : new XmlUrlResolver ();
+                       r.Href = res.ResolveUri (BaseURI != null ? new Uri (BaseURI) : null, href).AbsoluteUri;
+                       r.NSContext = ContextNamespace;
+                       if (!IsEmptyElement) {
+                               Read ();
+                               expectEnd ("externalRef");
+                       }
+                       else
+                               Read ();
+                       return r;
+               }
+
+               private RelaxngParentRef ReadParentRefPattern ()
+               {
+                       RelaxngParentRef r = new RelaxngParentRef ();
+                       FillLocation (r);
+                       expect ("parentRef");
+                       r.Name = GetNameAttribute ();
+                       if (!IsEmptyElement) {
+                               Read ();
+                               expectEnd ("parentRef");
+                       }
+                       else
+                               Read ();
+                       return r;
+               }
+
+               private RelaxngEmpty ReadEmptyPattern ()
+               {
+                       expect ("empty");
+
+                       if (MoveToFirstAttribute ()) {
+                               do {
+                                       if (NamespaceURI == String.Empty && LocalName != "datatypeLibrary")
+                                               throw new RelaxngException ("Invalid attribute.");
+                               } while (MoveToNextAttribute ());
+                               MoveToElement ();
+                       }
+
+                       if (!IsEmptyElement) {
+                               Read ();
+                               expectEnd ("empty");
+                       }
+                       else
+                               Read ();
+
+                       RelaxngEmpty empty = new RelaxngEmpty ();
+                       FillLocation (empty);
+                       return empty;
+               }
+
+               private RelaxngText ReadTextPattern ()
+               {
+                       expect ("text");
+
+                       if (MoveToFirstAttribute ()) {
+                               do {
+                                       if (NamespaceURI == String.Empty && LocalName != "datatypeLibrary")
+                                               throw new RelaxngException ("Invalid attribute.");
+                               } while (MoveToNextAttribute ());
+                               MoveToElement ();
+                       }
+
+                       if (!IsEmptyElement) {
+                               Read ();
+                               expectEnd ("text");
+                       }
+                       else
+                               Read ();
+
+                       RelaxngText t = new RelaxngText ();
+                       FillLocation (t);
+                       return t;
+               }
+
+               private RelaxngData ReadDataPattern ()
+               {
+                       RelaxngData data = new RelaxngData ();
+                       FillLocation (data);
+
+                       expect ("data");
+                       data.Type = GetSpaceStrippedAttribute ("type", String.Empty);
+                       if (data.Type == null)
+                               throw new RelaxngException ("Attribute type is required.");
+                       data.DatatypeLibrary = DatatypeLibrary;
+
+                       if (MoveToFirstAttribute ()) {
+                               do {
+                                       if (NamespaceURI != String.Empty)
+                                               continue;
+                                       switch (LocalName) {
+                                       case "datatypeLibrary":
+                                       case "type":
+                                               break;
+                                       default:
+                                               throw new RelaxngException ("Invalid attribute.");
+                                       }
+                               } while (MoveToNextAttribute ());
+                               MoveToElement ();
+                       }
+
+                       if (!IsEmptyElement) {
+                               Read ();
+                               while (Name == "param") {
+                                       data.ParamList.Add (ReadParam ());
+                               }
+                               if (LocalName == "except")
+                                       data.Except = ReadPatternExcept ();
+                               expectEnd ("data");
+                       } else
+                               Read ();
+
+                       return data;
+               }
+
+               private RelaxngValue ReadValuePattern ()
+               {
+                       RelaxngValue v = new RelaxngValue ();
+                       FillLocation (v);
+                       expect ("value");
+
+                       if (MoveToFirstAttribute ()) {
+                               do {
+                                       if (NamespaceURI != String.Empty)
+                                               continue;
+                                       switch (LocalName) {
+                                       case "datatypeLibrary":
+                                       case "type":
+                                       case "ns":
+                                               break;
+                                       default:
+                                               throw new RelaxngException ("Invalid attribute.");
+                                       }
+                               } while (MoveToNextAttribute ());
+                               MoveToElement ();
+                       }
+
+                       if (MoveToAttribute ("type")) {
+                               v.Type = Value.Trim ();
+                               v.DatatypeLibrary = DatatypeLibrary;
+                       } else {
+                               v.Type = "token";
+                               v.DatatypeLibrary = "";
+                       }
+//                     v.Namespace = GetSpaceStrippedAttribute ("ns", String.Empty);
+                       MoveToElement ();
+                       if (IsEmptyElement) {
+                               v.Value = String.Empty;
+                               Read ();
+                       } else {
+                               v.Value = ReadString ();
+                               expectEnd ("value");
+                       }
+
+                       return v;
+               }
+
+               private RelaxngList ReadListPattern ()
+               {
+                       RelaxngList list = new RelaxngList ();
+                       FillLocation (list);
+                       expect ("list");
+                       Read ();
+                       ReadPatterns (list);
+                       expectEnd ("list");
+                       return list;
+               }
+
+               private RelaxngOneOrMore ReadOneOrMorePattern ()
+               {
+                       RelaxngOneOrMore o = new RelaxngOneOrMore ();
+                       FillLocation (o);
+                       expect ("oneOrMore");
+                       Read ();
+                       ReadPatterns (o);
+                       expectEnd ("oneOrMore");
+                       return o;
+               }
+
+               private RelaxngZeroOrMore ReadZeroOrMorePattern ()
+               {
+                       RelaxngZeroOrMore o = new RelaxngZeroOrMore ();
+                       FillLocation (o);
+                       expect ("zeroOrMore");
+                       Read ();
+                       ReadPatterns (o);
+                       expectEnd ("zeroOrMore");
+                       return o;
+               }
+
+               private RelaxngOptional ReadOptionalPattern ()
+               {
+                       RelaxngOptional o = new RelaxngOptional ();
+                       FillLocation (o);
+                       expect ("optional");
+                       Read ();
+                       ReadPatterns (o);
+                       expectEnd ("optional");
+                       return o;
+               }
+
+               private RelaxngMixed ReadMixedPattern ()
+               {
+                       RelaxngMixed o = new RelaxngMixed ();
+                       FillLocation (o);
+                       expect ("mixed");
+                       Read ();
+                       ReadPatterns (o);
+                       expectEnd ("mixed");
+                       return o;
+               }
+
+               private RelaxngGroup ReadGroupPattern ()
+               {
+                       RelaxngGroup g = new RelaxngGroup ();
+                       FillLocation (g);
+                       expect ("group");
+                       Read ();
+                       ReadPatterns (g);
+                       expectEnd ("group");
+                       return g;
+               }
+
+               private RelaxngInterleave ReadInterleavePattern ()
+               {
+                       RelaxngInterleave i = new RelaxngInterleave ();
+                       FillLocation (i);
+                       expect ("interleave");
+                       Read ();
+                       ReadPatterns (i);
+                       expectEnd ("interleave");
+                       return i;
+               }
+
+               private RelaxngChoice ReadChoicePattern ()
+               {
+                       RelaxngChoice c = new RelaxngChoice ();
+                       FillLocation (c);
+                       expect ("choice");
+                       Read ();
+                       ReadPatterns (c);
+                       expectEnd ("choice");
+                       return c;
+               }
+
+               private RelaxngNotAllowed ReadNotAllowedPattern ()
+               {
+                       expect ("notAllowed");
+                       if (!IsEmptyElement) {
+                               Read ();
+                               expectEnd ("notAllowed");
+                       }
+                       else
+                               Read ();
+                       RelaxngNotAllowed na = new RelaxngNotAllowed ();
+                       FillLocation (na);
+                       return na;
+               }
+       }
 }
\ No newline at end of file