2 // Commons.Xml.Relaxng.RelaxngPattern.cs
\r
5 // Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
\r
7 // 2003 Atsushi Enomoto "No rights reserved."
\r
9 // Copyright (c) 2004 Novell Inc.
\r
10 // All rights reserved
\r
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 using System.Collections;
\r
38 using Commons.Xml.Relaxng.Derivative;
\r
39 using Commons.Xml.Relaxng.Rnc;
\r
42 using NSResolver = System.Xml.IXmlNamespaceResolver;
\r
44 using NSResolver = System.Xml.XmlNamespaceManager;
\r
47 namespace Commons.Xml.Relaxng
\r
49 #region Common abstract
\r
50 public abstract class RelaxngElementBase
\r
53 int lineNumber, linePosition;
\r
56 internal bool IsCompiled {
\r
57 get { return isCompiled; }
\r
58 set { isCompiled = value; }
\r
61 public int LineNumber {
\r
62 get { return lineNumber; }
\r
63 set { lineNumber = value; }
\r
66 public int LinePosition {
\r
67 get { return linePosition; }
\r
68 set { linePosition = value; }
\r
71 public string BaseUri {
\r
72 get { return baseUri; }
\r
73 set { baseUri = value; }
\r
76 public abstract void Write (XmlWriter writer);
\r
78 internal abstract void WriteRnc (RncWriter writer);
\r
81 public abstract class RelaxngSingleContentPattern : RelaxngPattern
\r
83 private RelaxngPatternList patterns = new RelaxngPatternList ();
\r
85 public RelaxngPatternList Patterns {
\r
86 get { return patterns; }
\r
89 internal RdpPattern makeSingle (RelaxngGrammar g)
\r
91 // Flatten patterns into RdpGroup. See 4.12.
\r
92 if (patterns.Count == 0)
\r
93 throw new RelaxngException (this, "No pattern contents.");
\r
94 RdpPattern p = ((RelaxngPattern) patterns [0]).Compile (g);
\r
95 if (patterns.Count == 1)
\r
97 for (int i=1; i<patterns.Count; i++) {
\r
98 p = new RdpGroup (p,
\r
99 ((RelaxngPattern) patterns [i]).Compile (g));
\r
104 internal override void CheckConstraints ()
\r
106 foreach (RelaxngPattern p in Patterns)
\r
107 p.CheckConstraints ();
\r
111 public abstract class RelaxngBinaryContentPattern : RelaxngPattern
\r
113 private RelaxngPatternList patterns = new RelaxngPatternList ();
\r
115 public RelaxngPatternList Patterns {
\r
116 get { return patterns; }
\r
119 internal RdpPattern makeBinary (RelaxngGrammar g)
\r
121 // Flatten patterns. See 4.12.
\r
122 if (patterns.Count == 0)
\r
123 throw new RelaxngException (this, "No pattern contents.");
\r
125 RdpPattern p = ((RelaxngPattern) patterns [0]).Compile (g);
\r
126 if (patterns.Count == 1)
\r
129 for (int i=1; i<patterns.Count; i++) {
\r
131 ((RelaxngPattern) patterns [i]).Compile (g);
\r
132 switch (this.PatternType) {
\r
133 case RelaxngPatternType.Choice:
\r
134 p = new RdpChoice (p, cp);
\r
136 case RelaxngPatternType.Group:
\r
137 p = new RdpGroup (p, cp);
\r
139 case RelaxngPatternType.Interleave:
\r
140 p = new RdpInterleave (p, cp);
\r
148 internal override void CheckConstraints ()
\r
150 foreach (RelaxngPattern p in Patterns)
\r
151 p.CheckConstraints ();
\r
156 #region Grammatical elements
\r
157 public interface IGrammarContent
\r
161 public class RelaxngStart : RelaxngElementBase, IGrammarContent
\r
166 public RelaxngStart ()
\r
170 public string Combine {
\r
171 get { return combine; }
\r
172 set { combine = value; }
\r
175 public RelaxngPattern Pattern {
\r
180 public override void Write (XmlWriter writer)
\r
182 writer.WriteStartElement ("", "start", RelaxngGrammar.NamespaceURI);
\r
183 if (combine != null)
\r
184 writer.WriteAttributeString ("combine", combine);
\r
186 writer.WriteEndElement ();
\r
189 internal override void WriteRnc (RncWriter writer)
\r
191 writer.WriteStart (this);
\r
194 internal RdpPattern Compile (RelaxngGrammar grammar)
\r
196 return p.Compile (grammar);
\r
200 public class RelaxngDefine : RelaxngElementBase, IGrammarContent
\r
203 private RelaxngPatternList patterns = new RelaxngPatternList ();
\r
206 public RelaxngDefine ()
\r
210 public RelaxngPatternList Patterns {
\r
211 get { return patterns; }
\r
214 public string Combine {
\r
215 get { return combine; }
\r
216 set { combine = value; }
\r
219 public string Name {
\r
220 get { return name; }
\r
221 set { name = value; }
\r
224 public override void Write (XmlWriter writer)
\r
226 writer.WriteStartElement ("", "define", RelaxngGrammar.NamespaceURI);
\r
227 writer.WriteAttributeString ("name", name);
\r
228 if (combine != null)
\r
229 writer.WriteAttributeString ("combine", combine);
\r
230 foreach (RelaxngPattern p in Patterns)
\r
232 writer.WriteEndElement ();
\r
235 internal override void WriteRnc (RncWriter writer)
\r
237 writer.WriteDefine (this);
\r
240 internal RdpPattern Compile (RelaxngGrammar grammar)
\r
242 return makeSingle (grammar);
\r
245 private RdpPattern makeSingle (RelaxngGrammar g)
\r
247 // Flatten patterns into RdpGroup. See 4.12.
\r
248 if (patterns.Count == 0)
\r
249 throw new RelaxngException (this, "No pattern contents.");
\r
250 RdpPattern p = ((RelaxngPattern) patterns [0]).Compile (g);
\r
251 if (patterns.Count == 1)
\r
253 for (int i=1; i<patterns.Count; i++) {
\r
254 p = new RdpGroup (p,
\r
255 ((RelaxngPattern) patterns [i]).Compile (g));
\r
261 public class RelaxngInclude : RelaxngElementBase, IGrammarContent
\r
264 RelaxngGrammarContentList starts = new RelaxngGrammarContentList ();
\r
265 RelaxngGrammarContentList defines = new RelaxngGrammarContentList ();
\r
266 RelaxngGrammarContentList divs = new RelaxngGrammarContentList ();
\r
269 public RelaxngInclude ()
\r
273 public string Href {
\r
274 get { return href; }
\r
275 set { href = value; }
\r
278 public RelaxngGrammarContentList Starts {
\r
279 get { return starts; }
\r
282 public RelaxngGrammarContentList Defines {
\r
283 get { return defines; }
\r
286 public RelaxngGrammarContentList Divs {
\r
287 get { return divs; }
\r
290 public string NSContext {
\r
292 set { ns = value; }
\r
295 public override void Write (XmlWriter writer)
\r
297 writer.WriteStartElement ("", "include", RelaxngGrammar.NamespaceURI);
\r
298 writer.WriteAttributeString ("href", href);
\r
299 foreach (RelaxngStart start in Starts)
\r
300 start.Write (writer);
\r
301 foreach (RelaxngDefine define in Defines)
\r
302 define.Write (writer);
\r
303 foreach (RelaxngDiv div in Divs)
\r
304 div.Write (writer);
\r
305 writer.WriteEndElement ();
\r
308 internal override void WriteRnc (RncWriter writer)
\r
310 writer.WriteInclude (this);
\r
313 // compile into div
\r
314 internal RelaxngDiv Compile (RelaxngGrammar grammar)
\r
316 grammar.CheckIncludeRecursion (Href);
\r
317 grammar.IncludedUris.Add (Href, Href);
\r
318 if (grammar.Resolver == null)
\r
319 throw new RelaxngException (this, "To compile 'include' element, XmlResolver is required.");
\r
320 Uri uri = grammar.Resolver.ResolveUri (BaseUri != String.Empty ? new Uri (BaseUri) : null, Href);
\r
321 XmlTextReader xtr = null;
\r
322 RelaxngGrammar g = null;
\r
324 xtr = new XmlTextReader (uri.AbsoluteUri, (Stream) grammar.Resolver.GetEntity (uri, null, typeof (Stream)));
\r
325 RelaxngReader r = new RelaxngReader (xtr, ns);
\r
326 r.MoveToContent ();
\r
327 g = r.ReadPattern () as RelaxngGrammar;
\r
332 throw new RelaxngException (this, "Included syntax must start with \"grammar\" element.");
\r
333 g.DataProvider = grammar.Provider;
\r
335 // process recursive inclusions.
\r
336 foreach (RelaxngInclude inc in g.Includes)
\r
337 g.Divs.Add (inc.Compile (grammar));
\r
339 // process this own div children.
\r
340 // each div subelements are also compiled.
\r
341 foreach (RelaxngDiv cdiv in divs)
\r
343 foreach (RelaxngDiv cdiv in g.Divs)
\r
346 // replace redifinitions into div.
\r
348 if (this.Starts.Count > 0 && g.Starts.Count == 0)
\r
349 throw new RelaxngException (this, "When the included grammar does not contain start components, this include component must not contain start components.");
\r
350 RelaxngGrammarContentList appliedStarts = (this.starts.Count > 0) ?
\r
351 this.starts : g.Starts;
\r
353 RelaxngDiv div = new RelaxngDiv ();
\r
354 div.BaseUri = this.BaseUri;
\r
355 div.LinePosition = this.LinePosition;
\r
356 div.LineNumber = this.LineNumber;
\r
358 foreach (RelaxngStart start in appliedStarts)
\r
359 div.Starts.Add (start);
\r
362 Hashtable overrides = new Hashtable ();
\r
363 Hashtable originalDefs = new Hashtable ();
\r
364 foreach (RelaxngDefine def in defines) {
\r
365 overrides.Add (def.Name, def.Name);
\r
366 div.Defines.Add (def);
\r
368 foreach (RelaxngDefine def in g.Defines) {
\r
369 originalDefs [def.Name] = def.Name;
\r
370 if (!overrides.ContainsKey (def.Name)) {
\r
371 div.Defines.Add (def);
\r
376 foreach (string name in overrides.Values)
\r
377 if (!originalDefs.ContainsKey (name))
\r
378 throw new RelaxngException (this, "The include component must not contain define components whose name does not appear in the included grammar component.");
\r
380 grammar.IncludedUris.Remove (Href);
\r
385 public class RelaxngDiv : RelaxngElementBase, IGrammarContent
\r
387 RelaxngGrammarContentList starts = new RelaxngGrammarContentList ();
\r
388 RelaxngGrammarContentList defines = new RelaxngGrammarContentList ();
\r
389 RelaxngGrammarContentList includes = new RelaxngGrammarContentList ();
\r
390 RelaxngGrammarContentList divs = new RelaxngGrammarContentList ();
\r
392 public RelaxngDiv ()
\r
396 public RelaxngGrammarContentList Starts {
\r
397 get { return starts; }
\r
400 public RelaxngGrammarContentList Defines {
\r
401 get { return defines; }
\r
404 public RelaxngGrammarContentList Includes {
\r
405 get { return includes; }
\r
408 public RelaxngGrammarContentList Divs {
\r
409 get { return divs; }
\r
412 public override void Write (XmlWriter writer)
\r
414 writer.WriteStartElement ("", "div", RelaxngGrammar.NamespaceURI);
\r
415 foreach (RelaxngStart start in Starts)
\r
416 start.Write (writer);
\r
417 foreach (RelaxngDefine define in Defines)
\r
418 define.Write (writer);
\r
419 foreach (RelaxngInclude include in Includes)
\r
420 include.Write (writer);
\r
421 foreach (RelaxngDiv div in Divs)
\r
422 div.Write (writer);
\r
423 writer.WriteEndElement ();
\r
426 internal override void WriteRnc (RncWriter writer)
\r
428 writer.WriteDiv (this);
\r
431 internal void Compile (RelaxngGrammar grammar)
\r
433 foreach (RelaxngDiv div in divs)
\r
434 div.Compile (grammar);
\r
435 foreach (RelaxngInclude inc in includes)
\r
436 inc.Compile (grammar).Compile (grammar); // compile compiled divs
\r
437 foreach (RelaxngStart start in starts)
\r
438 grammar.Starts.Add (start);
\r
439 foreach (RelaxngDefine define in defines)
\r
440 grammar.Defines.Add (define);
\r
445 #region RelaxngPatterns
\r
446 public abstract class RelaxngPattern : RelaxngElementBase
\r
450 public static RelaxngPattern Read (XmlReader xmlReader)
\r
452 return Read (xmlReader, null);
\r
455 public static RelaxngPattern Read (XmlReader xmlReader, RelaxngDatatypeProvider provider)
\r
457 RelaxngReader r = new RelaxngReader (xmlReader, null);
\r
458 if (r.ReadState == ReadState.Initial)
\r
460 r.MoveToContent ();
\r
461 RelaxngPattern p = r.ReadPattern ();
\r
462 p.DataProvider = provider;
\r
467 RdpPattern startRelaxngPattern;
\r
468 RelaxngDatatypeProvider provider;
\r
469 XmlResolver resolver;
\r
473 public XmlResolver XmlResolver {
\r
475 nullResolver = value == null;
\r
480 public abstract RelaxngPatternType PatternType { get; }
\r
481 public RelaxngDatatypeProvider DataProvider {
\r
490 public void Compile ()
\r
492 RelaxngGrammar g = null;
\r
493 if (this is RelaxngGrammar)
\r
494 g = (RelaxngGrammar) this;
\r
496 g = new RelaxngGrammar ();
\r
497 g.XmlResolver = this.Resolver;
\r
498 g.BaseUri = this.BaseUri;
\r
499 g.LineNumber = this.LineNumber;
\r
500 g.LinePosition = this.LinePosition;
\r
501 RelaxngStart st = new RelaxngStart ();
\r
502 st.BaseUri = this.BaseUri;
\r
503 st.LineNumber = this.LineNumber;
\r
504 st.LinePosition = this.LinePosition;
\r
507 g.Provider = provider;
\r
509 startRelaxngPattern = g.Compile (null);
\r
510 this.IsCompiled = true;
\r
513 public void WriteCompact (TextWriter writer)
\r
515 WriteCompact (new RncWriter (writer));
\r
518 public void WriteCompact (TextWriter writer, NSResolver res)
\r
520 WriteCompact (new RncWriter (writer, res));
\r
523 void WriteCompact (RncWriter writer)
\r
525 RelaxngGrammar g = this as RelaxngGrammar;
\r
526 string ns = (g != null ? g.DefaultNamespace : null);
\r
527 writer.WriteNamespaces (ns);
\r
532 internal XmlResolver Resolver {
\r
536 if (resolver == null)
\r
537 resolver = new XmlUrlResolver ();
\r
542 internal abstract void CheckConstraints ();
\r
544 protected RelaxngPattern ()
\r
548 internal abstract RdpPattern Compile (RelaxngGrammar grammar);
\r
550 internal RdpPattern StartPattern {
\r
551 get { return startRelaxngPattern; }
\r
555 public class RelaxngPatternList : CollectionBase
\r
557 public RelaxngPatternList ()
\r
561 public void Add (RelaxngPattern p)
\r
566 public RelaxngPattern this [int i] {
\r
567 get { return this.List [i] as RelaxngPattern; }
\r
568 set { this.List [i] = value; }
\r
571 public void Insert (int pos, RelaxngPattern p)
\r
573 List.Insert (pos, p);
\r
576 public void Remove (RelaxngPattern p)
\r
582 public class RelaxngGrammarContentList : CollectionBase
\r
584 public RelaxngGrammarContentList ()
\r
588 public void Add (IGrammarContent p)
\r
593 public IGrammarContent this [int i] {
\r
594 get { return this.List [i] as IGrammarContent; }
\r
595 set { this.List [i] = value; }
\r
598 public void Insert (int pos, IGrammarContent p)
\r
600 List.Insert (pos, p);
\r
603 public void Remove (IGrammarContent p)
\r
609 // strict to say, it's not a pattern ;)
\r
610 public class RelaxngNotAllowed : RelaxngPattern
\r
612 public RelaxngNotAllowed ()
\r
616 public override RelaxngPatternType PatternType {
\r
617 get { return RelaxngPatternType.NotAllowed; }
\r
620 public override void Write (XmlWriter writer)
\r
622 writer.WriteStartElement ("", "notAllowed", RelaxngGrammar.NamespaceURI);
\r
623 writer.WriteEndElement ();
\r
626 internal override void WriteRnc (RncWriter writer)
\r
628 writer.WriteNotAllowed (this);
\r
631 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
633 return RdpNotAllowed.Instance;
\r
636 internal override void CheckConstraints ()
\r
638 // nothing to check
\r
642 public class RelaxngEmpty : RelaxngPattern
\r
644 public RelaxngEmpty ()
\r
648 public override RelaxngPatternType PatternType {
\r
649 get { return RelaxngPatternType.Empty; }
\r
652 public override void Write (XmlWriter writer)
\r
654 writer.WriteStartElement ("", "empty", RelaxngGrammar.NamespaceURI);
\r
655 writer.WriteEndElement ();
\r
658 internal override void WriteRnc (RncWriter writer)
\r
660 writer.WriteEmpty (this);
\r
663 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
665 return RdpEmpty.Instance;
\r
668 internal override void CheckConstraints ()
\r
670 // nothing to check
\r
674 public class RelaxngText : RelaxngPattern
\r
676 public RelaxngText ()
\r
680 public override RelaxngPatternType PatternType {
\r
681 get { return RelaxngPatternType.Text; }
\r
684 public override void Write (XmlWriter writer)
\r
686 writer.WriteStartElement ("", "text", RelaxngGrammar.NamespaceURI);
\r
687 writer.WriteEndElement ();
\r
690 internal override void WriteRnc (RncWriter writer)
\r
692 writer.WriteText (this);
\r
695 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
697 return RdpText.Instance;
\r
700 internal override void CheckConstraints ()
\r
702 // nothing to check
\r
706 public abstract class RelaxngDataSupport : RelaxngPattern
\r
709 string datatypeLibrary;
\r
711 public string Type {
\r
712 get { return type; }
\r
713 set { type = value; }
\r
716 public string DatatypeLibrary {
\r
717 get { return datatypeLibrary; }
\r
718 set { datatypeLibrary = value; }
\r
721 internal void CheckDatatypeName ()
\r
723 // Data type name check is done in RdpData(Except) derivative creation.
\r
727 public class RelaxngData : RelaxngDataSupport
\r
729 RelaxngParamList paramList = new RelaxngParamList ();
\r
730 RelaxngExcept except;
\r
732 public RelaxngData ()
\r
736 public override RelaxngPatternType PatternType {
\r
737 get { return RelaxngPatternType.Data; }
\r
740 public RelaxngParamList ParamList {
\r
741 get { return paramList; }
\r
744 public RelaxngExcept Except {
\r
745 get { return except; }
\r
746 set { except = value; }
\r
749 public override void Write (XmlWriter writer)
\r
751 writer.WriteStartElement ("", "data", RelaxngGrammar.NamespaceURI);
\r
752 if (DatatypeLibrary != null && DatatypeLibrary != String.Empty)
\r
753 writer.WriteAttributeString ("datatypeLibrary", DatatypeLibrary);
\r
754 writer.WriteAttributeString ("type", Type);
\r
756 foreach (RelaxngParam p in ParamList)
\r
759 if (Except != null)
\r
760 Except.Write (writer);
\r
762 writer.WriteEndElement ();
\r
765 internal override void WriteRnc (RncWriter writer)
\r
767 writer.WriteData (this);
\r
770 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
772 // RdpParamList rdpl = new RdpParamList ();
\r
773 // foreach (RelaxngParam prm in this.paramList)
\r
774 // rdpl.Add (prm.Compile (grammar));
\r
775 RdpPattern p = null;
\r
776 if (this.except != null) {
\r
777 if (except.Patterns.Count == 0)
\r
778 throw new RelaxngException (this, "data except pattern have no children.");
\r
779 p = except.Patterns [0].Compile (grammar);
\r
780 for (int i=1; i<except.Patterns.Count; i++)
\r
781 p = new RdpChoice (p,
\r
782 except.Patterns [i].Compile (grammar));
\r
786 if (this.except != null)
\r
787 return new RdpDataExcept (new RdpDatatype (DatatypeLibrary, Type, ParamList, grammar.Provider), p);
\r
789 return new RdpData (new RdpDatatype (DatatypeLibrary, Type, ParamList, grammar.Provider));
\r
792 internal override void CheckConstraints ()
\r
794 CheckDatatypeName ();
\r
798 public class RelaxngValue : RelaxngDataSupport
\r
802 public override RelaxngPatternType PatternType {
\r
803 get { return RelaxngPatternType.Value; }
\r
806 public string Value {
\r
807 get { return value; }
\r
808 set { this.value = value; }
\r
811 public override void Write (XmlWriter writer)
\r
813 writer.WriteStartElement ("", "value", RelaxngGrammar.NamespaceURI);
\r
814 if (Type != null) {
\r
815 writer.WriteStartAttribute ("type", String.Empty);
\r
816 if (DatatypeLibrary != null && DatatypeLibrary != String.Empty)
\r
817 writer.WriteAttributeString ("datatypeLibrary", DatatypeLibrary);
\r
818 writer.WriteAttributeString ("type", Type);
\r
820 writer.WriteString (Value);
\r
821 writer.WriteEndElement ();
\r
824 internal override void WriteRnc (RncWriter writer)
\r
826 writer.WriteValue (this);
\r
829 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
832 return new RdpValue (new RdpDatatype (DatatypeLibrary,
\r
833 Type, null, grammar.Provider), value);
\r
836 internal override void CheckConstraints ()
\r
838 CheckDatatypeName ();
\r
842 public class RelaxngList : RelaxngSingleContentPattern
\r
844 internal RelaxngList ()
\r
848 public override RelaxngPatternType PatternType {
\r
849 get { return RelaxngPatternType.List; }
\r
852 public override void Write (XmlWriter writer)
\r
854 writer.WriteStartElement ("", "list", RelaxngGrammar.NamespaceURI);
\r
855 foreach (RelaxngPattern p in Patterns)
\r
857 writer.WriteEndElement ();
\r
860 internal override void WriteRnc (RncWriter writer)
\r
862 writer.WriteList (this);
\r
865 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
869 return new RdpList (makeSingle (grammar));
\r
872 internal override void CheckConstraints ()
\r
874 // nothing to check
\r
878 public class RelaxngElement : RelaxngSingleContentPattern
\r
880 RelaxngNameClass nc;
\r
882 public RelaxngElement ()
\r
886 public RelaxngNameClass NameClass {
\r
888 set { nc = value; }
\r
891 public override RelaxngPatternType PatternType {
\r
892 get { return RelaxngPatternType.Element; }
\r
895 public override void Write (XmlWriter writer)
\r
897 writer.WriteStartElement ("", "element", RelaxngGrammar.NamespaceURI);
\r
899 foreach (RelaxngPattern p in Patterns)
\r
901 writer.WriteEndElement ();
\r
904 internal override void WriteRnc (RncWriter writer)
\r
906 writer.WriteElement (this);
\r
909 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
911 return new RdpElement (
\r
912 nc.Compile (grammar), this.makeSingle (grammar));
\r
915 internal override void CheckConstraints ()
\r
917 NameClass.CheckConstraints (false, false);
\r
919 foreach (RelaxngPattern p in Patterns)
\r
920 p.CheckConstraints ();
\r
924 public class RelaxngAttribute : RelaxngPattern
\r
926 RelaxngNameClass nc;
\r
929 public RelaxngAttribute ()
\r
933 public RelaxngPattern Pattern {
\r
938 public RelaxngNameClass NameClass {
\r
940 set { nc = value; }
\r
943 public override RelaxngPatternType PatternType {
\r
944 get { return RelaxngPatternType.Attribute; }
\r
947 public override void Write (XmlWriter writer)
\r
949 writer.WriteStartElement ("", "attribute", RelaxngGrammar.NamespaceURI);
\r
953 writer.WriteEndElement ();
\r
956 internal override void WriteRnc (RncWriter writer)
\r
958 writer.WriteAttribute (this);
\r
961 private void checkInvalidAttrNameClass (RdpNameClass nc)
\r
963 string xmlnsNS = "http://www.w3.org/2000/xmlns";
\r
964 RdpNameClassChoice choice = nc as RdpNameClassChoice;
\r
965 if (choice != null) {
\r
966 checkInvalidAttrNameClass (choice.LValue);
\r
967 checkInvalidAttrNameClass (choice.RValue);
\r
970 RdpAnyNameExcept except = nc as RdpAnyNameExcept;
\r
971 if (except != null) {
\r
972 checkInvalidAttrNameClass (except.ExceptNameClass);
\r
975 if (nc is RdpAnyName)
\r
978 RdpName n = nc as RdpName;
\r
980 if (n.NamespaceURI == xmlnsNS)
\r
981 throw new RelaxngException (this, "cannot specify \"" + xmlnsNS + "\" for name of attribute.");
\r
982 if (n.LocalName == "xmlns" && n.NamespaceURI == "")
\r
983 throw new RelaxngException (this, "cannot specify \"xmlns\" inside empty ns context.");
\r
985 RdpNsName nn = nc as RdpNsName;
\r
986 if (nn.NamespaceURI == "http://www.w3.org/2000/xmlns")
\r
987 throw new RelaxngException (this, "cannot specify \"" + xmlnsNS + "\" for name of attribute.");
\r
988 RdpNsNameExcept x = nc as RdpNsNameExcept;
\r
990 checkInvalidAttrNameClass (x.ExceptNameClass);
\r
994 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
997 RdpNameClass cnc = nc.Compile (grammar);
\r
998 this.checkInvalidAttrNameClass (cnc);
\r
1000 return new RdpAttribute (cnc,
\r
1002 p.Compile (grammar) :
\r
1003 RdpText.Instance);
\r
1006 internal override void CheckConstraints ()
\r
1008 NameClass.CheckConstraints (false, false);
\r
1011 p.CheckConstraints ();
\r
1015 internal class RdpUnresolvedRef : RdpPattern
\r
1018 // bool parentRef;
\r
1019 RelaxngGrammar targetGrammar;
\r
1020 RdpPattern referencedPattern;
\r
1022 public RdpUnresolvedRef (string name, RelaxngGrammar g)
\r
1025 // this.parentRef = parentRef;
\r
1026 targetGrammar = g;
\r
1029 public string Name {
\r
1030 get { return name; }
\r
1031 set { name = value; }
\r
1034 public RdpPattern RefPattern {
\r
1035 get { return referencedPattern; }
\r
1036 set { referencedPattern = value; }
\r
1039 // public bool IsParentRef {
\r
1040 // get { return parentRef; }
\r
1043 public RelaxngGrammar TargetGrammar {
\r
1044 get { return targetGrammar; }
\r
1047 public override RelaxngPatternType PatternType {
\r
1048 get { return RelaxngPatternType.Ref; }
\r
1051 public override RdpContentType ContentType {
\r
1052 get { return RdpContentType.Empty; }
\r
1056 public override bool Nullable {
\r
1058 throw new InvalidOperationException ("Internal error: should not reach.");
\r
1062 public override void GetLabels (Hashtable elements, Hashtable attributes, bool collectNameClass)
\r
1064 // Now it could reach (CheckNameOverlap) so comment out here.
\r
1065 // throw new InvalidOperationException ("Internal error: should not reach.");
\r
1068 internal override RdpPattern ExpandRef (Hashtable defs)
\r
1070 return referencedPattern.ExpandRef (defs);
\r
1073 internal override void MarkReachableDefs ()
\r
1075 TargetGrammar.MarkReacheableDefine (this.name);
\r
1078 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
\r
1080 referencedPattern =
\r
1081 referencedPattern.ReduceEmptyAndNotAllowed (
\r
1082 ref result, visited);
\r
1086 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
\r
1088 // throw new InvalidOperationException ();
\r
1091 internal override bool ContainsText ()
\r
1094 // throw new InvalidOperationException ();
\r
1098 public class RelaxngRef : RelaxngPattern
\r
1102 public RelaxngRef ()
\r
1106 public string Name {
\r
1107 get { return name; }
\r
1108 set { name = value; }
\r
1111 public override RelaxngPatternType PatternType {
\r
1112 get { return RelaxngPatternType.Ref; }
\r
1115 public override void Write (XmlWriter writer)
\r
1117 writer.WriteStartElement ("", "ref", RelaxngGrammar.NamespaceURI);
\r
1118 writer.WriteAttributeString ("name", name);
\r
1119 writer.WriteEndElement ();
\r
1122 internal override void WriteRnc (RncWriter writer)
\r
1124 writer.WriteRef (this);
\r
1127 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1129 // Important!! This compile method only generates stub.
\r
1130 IsCompiled = false;
\r
1131 return new RdpUnresolvedRef (name, grammar);
\r
1134 internal override void CheckConstraints ()
\r
1136 // nothing to check
\r
1140 public class RelaxngParentRef : RelaxngPattern
\r
1144 public RelaxngParentRef ()
\r
1148 public string Name {
\r
1149 get { return name; }
\r
1150 set { name = value; }
\r
1153 public override RelaxngPatternType PatternType {
\r
1154 get { return RelaxngPatternType.ParentRef; }
\r
1157 public override void Write (XmlWriter writer)
\r
1159 writer.WriteStartElement ("", "parentRef", RelaxngGrammar.NamespaceURI);
\r
1160 writer.WriteAttributeString ("name", name);
\r
1161 writer.WriteEndElement ();
\r
1164 internal override void WriteRnc (RncWriter writer)
\r
1166 writer.WriteParentRef (this);
\r
1169 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1171 IsCompiled = false;
\r
1172 return new RdpUnresolvedRef (name, grammar.ParentGrammar);
\r
1175 internal override void CheckConstraints ()
\r
1177 // nothing to check
\r
1181 public class RelaxngExternalRef : RelaxngPattern
\r
1186 public RelaxngExternalRef ()
\r
1190 public string Href {
\r
1191 get { return href; }
\r
1192 set { href = value; }
\r
1195 public string NSContext {
\r
1196 get { return ns; }
\r
1197 set { ns = value; }
\r
1200 public override RelaxngPatternType PatternType {
\r
1201 get { return RelaxngPatternType.ExternalRef; }
\r
1204 public override void Write (XmlWriter writer)
\r
1206 writer.WriteStartElement ("", "externalRef", RelaxngGrammar.NamespaceURI);
\r
1207 writer.WriteAttributeString ("href", Href);
\r
1208 writer.WriteEndElement ();
\r
1211 internal override void WriteRnc (RncWriter writer)
\r
1213 writer.WriteExternalRef (this);
\r
1216 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1218 grammar.CheckIncludeRecursion (Href);
\r
1219 grammar.IncludedUris.Add (Href, Href);
\r
1220 if (grammar.Resolver == null)
\r
1221 throw new RelaxngException (this, "To compile 'include' element, XmlResolver is required.");
\r
1222 Uri uri = grammar.Resolver.ResolveUri (BaseUri != String.Empty ? new Uri (BaseUri) : null, Href);
\r
1223 XmlTextReader xtr = null;
\r
1225 xtr = new XmlTextReader (uri.AbsoluteUri, (Stream) grammar.Resolver.GetEntity (uri, null, typeof (Stream)));
\r
1226 RelaxngReader r = new RelaxngReader (xtr, ns);
\r
1227 r.MoveToContent ();
\r
1228 RelaxngPattern p = r.ReadPattern ();
\r
1229 p.DataProvider = grammar.Provider;
\r
1231 RdpPattern ret = p.Compile (grammar);
\r
1233 grammar.IncludedUris.Remove (Href);
\r
1243 internal override void CheckConstraints ()
\r
1245 // nothing to check
\r
1249 public class RelaxngOneOrMore : RelaxngSingleContentPattern
\r
1251 public RelaxngOneOrMore ()
\r
1255 public override RelaxngPatternType PatternType {
\r
1256 get { return RelaxngPatternType.OneOrMore; }
\r
1259 public override void Write (XmlWriter writer)
\r
1261 writer.WriteStartElement ("", "oneOrMore", RelaxngGrammar.NamespaceURI);
\r
1262 foreach (RelaxngPattern p in Patterns)
\r
1264 writer.WriteEndElement ();
\r
1267 internal override void WriteRnc (RncWriter writer)
\r
1269 writer.WriteOneOrMore (this);
\r
1272 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1274 IsCompiled = true;
\r
1275 return new RdpOneOrMore (makeSingle (grammar));
\r
1279 public class RelaxngZeroOrMore : RelaxngSingleContentPattern
\r
1281 public RelaxngZeroOrMore ()
\r
1285 public override RelaxngPatternType PatternType {
\r
1286 get { return RelaxngPatternType.ZeroOrMore; }
\r
1289 public override void Write (XmlWriter writer)
\r
1291 writer.WriteStartElement ("", "zeroOrMore", RelaxngGrammar.NamespaceURI);
\r
1292 foreach (RelaxngPattern p in Patterns)
\r
1294 writer.WriteEndElement ();
\r
1297 internal override void WriteRnc (RncWriter writer)
\r
1299 writer.WriteZeroOrMore (this);
\r
1302 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1304 IsCompiled = true;
\r
1305 return new RdpChoice (
\r
1306 new RdpOneOrMore (makeSingle (grammar)),
\r
1307 RdpEmpty.Instance);
\r
1311 public class RelaxngOptional : RelaxngSingleContentPattern
\r
1313 public RelaxngOptional ()
\r
1317 public override RelaxngPatternType PatternType {
\r
1318 get { return RelaxngPatternType.Optional; }
\r
1321 public override void Write (XmlWriter writer)
\r
1323 writer.WriteStartElement ("", "optional", RelaxngGrammar.NamespaceURI);
\r
1324 foreach (RelaxngPattern p in Patterns)
\r
1326 writer.WriteEndElement ();
\r
1329 internal override void WriteRnc (RncWriter writer)
\r
1331 writer.WriteOptional (this);
\r
1334 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1336 IsCompiled = true;
\r
1337 return new RdpChoice (
\r
1338 makeSingle (grammar), RdpEmpty.Instance);
\r
1342 public class RelaxngMixed : RelaxngSingleContentPattern
\r
1344 public RelaxngMixed ()
\r
1348 public override RelaxngPatternType PatternType {
\r
1349 get { return RelaxngPatternType.Mixed; }
\r
1352 public override void Write (XmlWriter writer)
\r
1354 writer.WriteStartElement ("", "mixed", RelaxngGrammar.NamespaceURI);
\r
1355 foreach (RelaxngPattern p in Patterns)
\r
1357 writer.WriteEndElement ();
\r
1360 internal override void WriteRnc (RncWriter writer)
\r
1362 writer.WriteMixed (this);
\r
1365 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1367 IsCompiled = true;
\r
1368 return new RdpInterleave (makeSingle (grammar), RdpText.Instance);
\r
1372 public class RelaxngChoice : RelaxngBinaryContentPattern
\r
1374 public RelaxngChoice ()
\r
1378 public override RelaxngPatternType PatternType {
\r
1379 get { return RelaxngPatternType.Choice; }
\r
1382 public override void Write (XmlWriter writer)
\r
1384 writer.WriteStartElement ("", "choice", RelaxngGrammar.NamespaceURI);
\r
1385 foreach (RelaxngPattern p in Patterns)
\r
1387 writer.WriteEndElement ();
\r
1390 internal override void WriteRnc (RncWriter writer)
\r
1392 writer.WriteChoice (this);
\r
1395 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1397 IsCompiled = true;
\r
1398 return makeBinary (grammar);
\r
1402 public class RelaxngGroup : RelaxngBinaryContentPattern
\r
1404 public RelaxngGroup ()
\r
1408 public override RelaxngPatternType PatternType {
\r
1409 get { return RelaxngPatternType.Group; }
\r
1412 public override void Write (XmlWriter writer)
\r
1414 writer.WriteStartElement ("", "group", RelaxngGrammar.NamespaceURI);
\r
1415 foreach (RelaxngPattern p in Patterns)
\r
1417 writer.WriteEndElement ();
\r
1420 internal override void WriteRnc (RncWriter writer)
\r
1422 writer.WriteGroup (this);
\r
1425 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1427 IsCompiled = true;
\r
1428 return makeBinary (grammar);
\r
1432 public class RelaxngInterleave : RelaxngBinaryContentPattern
\r
1434 public RelaxngInterleave ()
\r
1438 public override RelaxngPatternType PatternType {
\r
1439 get { return RelaxngPatternType.Interleave; }
\r
1442 public override void Write (XmlWriter writer)
\r
1444 writer.WriteStartElement ("", "interleave", RelaxngGrammar.NamespaceURI);
\r
1445 foreach (RelaxngPattern p in Patterns)
\r
1447 writer.WriteEndElement ();
\r
1450 internal override void WriteRnc (RncWriter writer)
\r
1452 writer.WriteInterleave (this);
\r
1455 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1457 IsCompiled = true;
\r
1458 return makeBinary (grammar);
\r
1462 public class RelaxngParam : RelaxngElementBase
\r
1467 public RelaxngParam ()
\r
1471 public RelaxngParam (string name, string value)
\r
1474 this.value = value;
\r
1477 public string Name {
\r
1478 get { return name; }
\r
1479 set { name = value; }
\r
1482 public string Value {
\r
1483 get { return value; }
\r
1484 set { this.value = value; }
\r
1487 public override void Write (XmlWriter writer)
\r
1489 writer.WriteStartElement ("", "param", RelaxngGrammar.NamespaceURI);
\r
1490 writer.WriteAttributeString ("name", name);
\r
1491 writer.WriteString (Value);
\r
1492 writer.WriteEndElement ();
\r
1495 internal override void WriteRnc (RncWriter writer)
\r
1497 writer.WriteParam (this);
\r
1500 internal RdpParam Compile (RelaxngGrammar grammar)
\r
1502 IsCompiled = true;
\r
1503 return new RdpParam (name, value);
\r
1507 public class RelaxngParamList : CollectionBase
\r
1509 public RelaxngParamList ()
\r
1513 public void Add (RelaxngParam p)
\r
1518 public RelaxngParam this [int i] {
\r
1519 get { return this.List [i] as RelaxngParam; }
\r
1520 set { this.List [i] = value; }
\r
1523 public void Insert (int pos, RelaxngParam p)
\r
1525 List.Insert (pos, p);
\r
1528 public void Remove (RelaxngParam p)
\r
1534 public class RelaxngExcept : RelaxngElementBase
\r
1536 RelaxngPatternList patterns = new RelaxngPatternList ();
\r
1538 public RelaxngExcept ()
\r
1542 public RelaxngPatternList Patterns {
\r
1543 get { return patterns; }
\r
1546 public override void Write (XmlWriter writer)
\r
1548 writer.WriteStartElement ("", "except", RelaxngGrammar.NamespaceURI);
\r
1549 foreach (RelaxngPattern p in Patterns)
\r
1551 writer.WriteEndElement ();
\r
1554 internal override void WriteRnc (RncWriter writer)
\r
1556 writer.WriteDataExcept (this);
\r
1560 internal class RelaxngRefPattern
\r
1562 RelaxngPattern patternRef;
\r
1565 // When we found ref, use it.
\r
1566 public RelaxngRefPattern (string name)
\r
1571 // When we found define, use it.
\r
1572 public RelaxngRefPattern (RelaxngPattern patternRef)
\r
1574 this.patternRef = patternRef;
\r
1577 public string Name {
\r
1578 get { return name; }
\r
1581 public RelaxngPattern PatternRef {
\r
1582 get { return patternRef; }
\r
1583 set { patternRef = value; }
\r