-//\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