**** Merged from MCS ****
[mono-project.git] / mcs / class / Commons.Xml.Relaxng / Commons.Xml.Relaxng / RelaxngPattern.cs
blob3dfc8be66ede4726872eec83a60220b6a8f70355
1 //
2 // Commons.Xml.Relaxng.RelaxngPattern.cs
3 //
4 // Author:
5 // Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
6 //
7 // 2003 Atsushi Enomoto "No rights reserved."
8 //
9 // Copyright (c) 2004 Novell Inc.
10 // All rights reserved
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 //
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 //
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System;
35 using System.Collections;
36 using System.IO;
37 using System.Xml;
38 using Commons.Xml.Relaxng.Derivative;
40 namespace Commons.Xml.Relaxng
42 #region Common abstract
43 public abstract class RelaxngElementBase
45 bool isCompiled;
46 int lineNumber, linePosition;
47 string baseUri;
49 internal bool IsCompiled {
50 get { return isCompiled; }
51 set { isCompiled = value; }
54 public int LineNumber {
55 get { return lineNumber; }
56 set { lineNumber = value; }
59 public int LinePosition {
60 get { return linePosition; }
61 set { linePosition = value; }
64 public string BaseUri {
65 get { return baseUri; }
66 set { baseUri = value; }
69 public abstract void Write (XmlWriter write);
72 public abstract class RelaxngSingleContentPattern : RelaxngPattern
74 private RelaxngPatternList patterns = new RelaxngPatternList ();
76 public RelaxngPatternList Patterns {
77 get { return patterns; }
80 internal RdpPattern makeSingle (RelaxngGrammar g)
82 // Flatten patterns into RdpGroup. See 4.12.
83 if (patterns.Count == 0)
84 throw new RelaxngException ("No pattern contents.");
85 RdpPattern p = ((RelaxngPattern) patterns [0]).Compile (g);
86 if (patterns.Count == 1)
87 return p;
88 for (int i=1; i<patterns.Count; i++) {
89 p = new RdpGroup (p,
90 ((RelaxngPattern) patterns [i]).Compile (g));
92 return p;
95 internal override void CheckConstraints ()
97 foreach (RelaxngPattern p in Patterns)
98 p.CheckConstraints ();
102 public abstract class RelaxngBinaryContentPattern : RelaxngPattern
104 private RelaxngPatternList patterns = new RelaxngPatternList ();
106 public RelaxngPatternList Patterns {
107 get { return patterns; }
110 internal RdpPattern makeBinary (RelaxngGrammar g)
112 // Flatten patterns. See 4.12.
113 if (patterns.Count == 0)
114 throw new RelaxngException ("No pattern contents.");
116 RdpPattern p = ((RelaxngPattern) patterns [0]).Compile (g);
117 if (patterns.Count == 1)
118 return p;
120 for (int i=1; i<patterns.Count; i++) {
121 RdpPattern cp =
122 ((RelaxngPattern) patterns [i]).Compile (g);
123 switch (this.PatternType) {
124 case RelaxngPatternType.Choice:
125 p = new RdpChoice (p, cp);
126 break;
127 case RelaxngPatternType.Group:
128 p = new RdpGroup (p, cp);
129 break;
130 case RelaxngPatternType.Interleave:
131 p = new RdpInterleave (p, cp);
132 break;
136 return p;
139 internal override void CheckConstraints ()
141 foreach (RelaxngPattern p in Patterns)
142 p.CheckConstraints ();
145 #endregion
147 #region Grammatical elements
148 public interface IGrammarContent
152 public class RelaxngStart : RelaxngElementBase, IGrammarContent
154 RelaxngPattern p;
155 string combine;
157 public RelaxngStart ()
161 public string Combine {
162 get { return combine; }
163 set { combine = value; }
166 public RelaxngPattern Pattern {
167 get { return p; }
168 set { p = value; }
171 public override void Write (XmlWriter writer)
173 writer.WriteStartElement ("", "start", RelaxngGrammar.NamespaceURI);
174 if (combine != null)
175 writer.WriteAttributeString ("combine", combine);
176 p.Write (writer);
177 writer.WriteEndElement ();
180 internal RdpPattern Compile (RelaxngGrammar grammar)
182 return p.Compile (grammar);
186 public class RelaxngDefine : RelaxngElementBase, IGrammarContent
188 string name;
189 private RelaxngPatternList patterns = new RelaxngPatternList ();
190 string combine;
192 public RelaxngDefine ()
196 public RelaxngPatternList Patterns {
197 get { return patterns; }
200 public string Combine {
201 get { return combine; }
202 set { combine = value; }
205 public string Name {
206 get { return name; }
207 set { name = value; }
210 public override void Write (XmlWriter writer)
212 writer.WriteStartElement ("", "define", RelaxngGrammar.NamespaceURI);
213 writer.WriteAttributeString ("name", name);
214 if (combine != null)
215 writer.WriteAttributeString ("combine", combine);
216 foreach (RelaxngPattern p in Patterns)
217 p.Write (writer);
218 writer.WriteEndElement ();
221 internal RdpPattern Compile (RelaxngGrammar grammar)
223 return makeSingle (grammar);
226 private RdpPattern makeSingle (RelaxngGrammar g)
228 // Flatten patterns into RdpGroup. See 4.12.
229 if (patterns.Count == 0)
230 throw new RelaxngException ("No pattern contents.");
231 RdpPattern p = ((RelaxngPattern) patterns [0]).Compile (g);
232 if (patterns.Count == 1)
233 return p;
234 for (int i=1; i<patterns.Count; i++) {
235 p = new RdpGroup (p,
236 ((RelaxngPattern) patterns [i]).Compile (g));
238 return p;
242 public class RelaxngInclude : RelaxngElementBase, IGrammarContent
244 string href;
245 RelaxngGrammarContentList starts = new RelaxngGrammarContentList ();
246 RelaxngGrammarContentList defines = new RelaxngGrammarContentList ();
247 RelaxngGrammarContentList divs = new RelaxngGrammarContentList ();
248 string ns;
250 public RelaxngInclude ()
254 public string Href {
255 get { return href; }
256 set { href = value; }
259 public RelaxngGrammarContentList Starts {
260 get { return starts; }
263 public RelaxngGrammarContentList Defines {
264 get { return defines; }
267 public RelaxngGrammarContentList Divs {
268 get { return divs; }
271 public string NSContext {
272 get { return ns; }
273 set { ns = value; }
276 public override void Write (XmlWriter writer)
278 writer.WriteStartElement ("", "include", RelaxngGrammar.NamespaceURI);
279 writer.WriteAttributeString ("href", href);
280 foreach (RelaxngStart start in Starts)
281 start.Write (writer);
282 foreach (RelaxngDefine define in Defines)
283 define.Write (writer);
284 foreach (RelaxngDiv div in Divs)
285 div.Write (writer);
286 writer.WriteEndElement ();
289 // compile into div
290 internal RelaxngDiv Compile (RelaxngGrammar grammar)
292 grammar.CheckIncludeRecursion (Href);
293 grammar.IncludedUris.Add (Href, Href);
294 if (grammar.Resolver == null)
295 throw new RelaxngException ("To compile 'include' element, XmlResolver is required.");
296 Uri uri = grammar.Resolver.ResolveUri (BaseUri != String.Empty ? new Uri (BaseUri) : null, Href);
297 XmlTextReader xtr = null;
298 RelaxngGrammar g = null;
299 try {
300 xtr = new XmlTextReader (uri.AbsoluteUri, (Stream) grammar.Resolver.GetEntity (uri, null, typeof (Stream)));
301 RelaxngReader r = new RelaxngReader (xtr, ns);
302 r.MoveToContent ();
303 g = r.ReadPattern () as RelaxngGrammar;
304 } finally {
305 xtr.Close ();
307 if (g == null)
308 throw new RelaxngException ("Included syntax must start with \"grammar\" element.");
309 g.DataProvider = grammar.Provider;
311 // process recursive inclusions.
312 foreach (RelaxngInclude inc in g.Includes)
313 g.Divs.Add (inc.Compile (grammar));
315 // process this own div children.
316 // each div subelements are also compiled.
317 foreach (RelaxngDiv cdiv in divs)
318 cdiv.Compile (g);
319 foreach (RelaxngDiv cdiv in g.Divs)
320 cdiv.Compile (g);
322 // replace redifinitions into div.
323 // starts.
324 if (this.Starts.Count > 0 && g.Starts.Count == 0)
325 throw new RelaxngException ("When the included grammar does not contain start components, this include component must not contain start components.");
326 RelaxngGrammarContentList appliedStarts = (this.starts.Count > 0) ?
327 this.starts : g.Starts;
329 RelaxngDiv div = new RelaxngDiv ();
330 div.BaseUri = this.BaseUri;
331 div.LinePosition = this.LinePosition;
332 div.LineNumber = this.LineNumber;
334 foreach (RelaxngStart start in appliedStarts)
335 div.Starts.Add (start);
337 // defines.
338 Hashtable overrides = new Hashtable ();
339 Hashtable originalDefs = new Hashtable ();
340 foreach (RelaxngDefine def in defines) {
341 overrides.Add (def.Name, def.Name);
342 div.Defines.Add (def);
344 foreach (RelaxngDefine def in g.Defines) {
345 originalDefs.Add (def.Name, def.Name);
346 if (overrides [def.Name] == null)
347 div.Defines.Add (def);
348 // else discard.
350 foreach (string name in overrides.Values)
351 if (!originalDefs.Contains (name))
352 throw new RelaxngException ("The include component must not contain define components whose name does not appear in the included grammar component.");
354 grammar.IncludedUris.Remove (Href);
355 return div;
359 public class RelaxngDiv : RelaxngElementBase, IGrammarContent
361 RelaxngGrammarContentList starts = new RelaxngGrammarContentList ();
362 RelaxngGrammarContentList defines = new RelaxngGrammarContentList ();
363 RelaxngGrammarContentList includes = new RelaxngGrammarContentList ();
364 RelaxngGrammarContentList divs = new RelaxngGrammarContentList ();
366 public RelaxngDiv ()
370 public RelaxngGrammarContentList Starts {
371 get { return starts; }
374 public RelaxngGrammarContentList Defines {
375 get { return defines; }
378 public RelaxngGrammarContentList Includes {
379 get { return includes; }
382 public RelaxngGrammarContentList Divs {
383 get { return divs; }
386 public override void Write (XmlWriter writer)
388 writer.WriteStartElement ("", "div", RelaxngGrammar.NamespaceURI);
389 foreach (RelaxngStart start in Starts)
390 start.Write (writer);
391 foreach (RelaxngDefine define in Defines)
392 define.Write (writer);
393 foreach (RelaxngInclude include in Includes)
394 include.Write (writer);
395 foreach (RelaxngDiv div in Divs)
396 div.Write (writer);
397 writer.WriteEndElement ();
400 internal void Compile (RelaxngGrammar grammar)
402 foreach (RelaxngDiv div in divs)
403 div.Compile (grammar);
404 foreach (RelaxngInclude inc in includes)
405 inc.Compile (grammar).Compile (grammar); // compile compiled divs
406 foreach (RelaxngStart start in starts)
407 grammar.Starts.Add (start);
408 foreach (RelaxngDefine define in defines)
409 grammar.Defines.Add (define);
412 #endregion
414 #region RelaxngPatterns
415 public abstract class RelaxngPattern : RelaxngElementBase
417 // static
419 public static RelaxngPattern Read (XmlReader xmlReader)
421 return Read (xmlReader, null);
424 public static RelaxngPattern Read (XmlReader xmlReader, RelaxngDatatypeProvider provider)
426 RelaxngReader r = new RelaxngReader (xmlReader, null);
427 if (r.ReadState == ReadState.Initial)
428 r.Read ();
429 r.MoveToContent ();
430 RelaxngPattern p = r.ReadPattern ();
431 p.DataProvider = provider;
432 return p;
435 // Private Fields
436 RdpPattern startRelaxngPattern;
437 RelaxngDatatypeProvider provider;
438 XmlResolver resolver;
439 bool nullResolver;
441 // Public
442 public XmlResolver XmlResolver {
443 set {
444 nullResolver = value == null;
445 resolver = value;
449 public abstract RelaxngPatternType PatternType { get; }
450 public RelaxngDatatypeProvider DataProvider {
451 get {
452 return provider;
454 set {
455 provider = value;
459 public void Compile ()
461 RelaxngGrammar g = null;
462 if (this is RelaxngGrammar)
463 g = (RelaxngGrammar) this;
464 else {
465 g = new RelaxngGrammar ();
466 g.XmlResolver = this.Resolver;
467 g.BaseUri = this.BaseUri;
468 g.LineNumber = this.LineNumber;
469 g.LinePosition = this.LinePosition;
470 RelaxngStart st = new RelaxngStart ();
471 st.BaseUri = this.BaseUri;
472 st.LineNumber = this.LineNumber;
473 st.LinePosition = this.LinePosition;
474 st.Pattern = this;
475 g.Starts.Add (st);
476 g.Provider = provider;
478 startRelaxngPattern = g.Compile (null);
479 this.IsCompiled = true;
483 // Internal
484 internal XmlResolver Resolver {
485 get {
486 if (nullResolver)
487 return null;
488 if (resolver == null)
489 resolver = new XmlUrlResolver ();
490 return resolver;
494 internal abstract void CheckConstraints ();
496 protected RelaxngPattern ()
500 internal abstract RdpPattern Compile (RelaxngGrammar grammar);
502 internal RdpPattern StartPattern {
503 get { return startRelaxngPattern; }
507 public class RelaxngPatternList : CollectionBase
509 public RelaxngPatternList ()
513 public void Add (RelaxngPattern p)
515 List.Add (p);
518 public RelaxngPattern this [int i] {
519 get { return this.List [i] as RelaxngPattern; }
520 set { this.List [i] = value; }
523 public void Insert (int pos, RelaxngPattern p)
525 List.Insert (pos, p);
528 public void Remove (RelaxngPattern p)
530 List.Remove (p);
534 public class RelaxngGrammarContentList : CollectionBase
536 public RelaxngGrammarContentList ()
540 public void Add (IGrammarContent p)
542 List.Add (p);
545 public IGrammarContent this [int i] {
546 get { return this.List [i] as IGrammarContent; }
547 set { this.List [i] = value; }
550 public void Insert (int pos, IGrammarContent p)
552 List.Insert (pos, p);
555 public void Remove (IGrammarContent p)
557 List.Remove (p);
561 // strict to say, it's not a pattern ;)
562 public class RelaxngNotAllowed : RelaxngPattern
564 public RelaxngNotAllowed ()
568 public override RelaxngPatternType PatternType {
569 get { return RelaxngPatternType.NotAllowed; }
572 public override void Write (XmlWriter writer)
574 writer.WriteStartElement ("", "notAllowed", RelaxngGrammar.NamespaceURI);
575 writer.WriteEndElement ();
578 internal override RdpPattern Compile (RelaxngGrammar grammar)
580 return RdpNotAllowed.Instance;
583 internal override void CheckConstraints ()
585 // nothing to check
589 public class RelaxngEmpty : RelaxngPattern
591 public RelaxngEmpty ()
595 public override RelaxngPatternType PatternType {
596 get { return RelaxngPatternType.Empty; }
599 public override void Write (XmlWriter writer)
601 writer.WriteStartElement ("", "empty", RelaxngGrammar.NamespaceURI);
602 writer.WriteEndElement ();
605 internal override RdpPattern Compile (RelaxngGrammar grammar)
607 return RdpEmpty.Instance;
610 internal override void CheckConstraints ()
612 // nothing to check
616 public class RelaxngText : RelaxngPattern
618 public RelaxngText ()
622 public override RelaxngPatternType PatternType {
623 get { return RelaxngPatternType.Text; }
626 public override void Write (XmlWriter writer)
628 writer.WriteStartElement ("", "text", RelaxngGrammar.NamespaceURI);
629 writer.WriteEndElement ();
632 internal override RdpPattern Compile (RelaxngGrammar grammar)
634 return RdpText.Instance;
637 internal override void CheckConstraints ()
639 // nothing to check
643 public abstract class RelaxngDataSupport : RelaxngPattern
645 string type;
646 string datatypeLibrary;
648 public string Type {
649 get { return type; }
650 set { type = value; }
653 public string DatatypeLibrary {
654 get { return datatypeLibrary; }
655 set { datatypeLibrary = value; }
658 internal void CheckDatatypeName ()
660 // Data type name check is done in RdpData(Except) derivative creation.
664 public class RelaxngData : RelaxngDataSupport
666 RelaxngParamList paramList = new RelaxngParamList ();
667 RelaxngExcept except;
669 public RelaxngData ()
673 public override RelaxngPatternType PatternType {
674 get { return RelaxngPatternType.Data; }
677 public RelaxngParamList ParamList {
678 get { return paramList; }
681 public RelaxngExcept Except {
682 get { return except; }
683 set { except = value; }
686 public override void Write (XmlWriter writer)
688 writer.WriteStartElement ("", "data", RelaxngGrammar.NamespaceURI);
689 if (DatatypeLibrary != null && DatatypeLibrary != String.Empty)
690 writer.WriteAttributeString ("xmlns", "data", "http://www.w3.org/2000/xmlns/", DatatypeLibrary);
691 writer.WriteStartAttribute ("type", String.Empty);
692 writer.WriteQualifiedName (Type, DatatypeLibrary);
693 writer.WriteEndAttribute ();
695 foreach (RelaxngParam p in ParamList)
696 p.Write (writer);
698 if (Except != null)
699 Except.Write (writer);
701 writer.WriteEndElement ();
704 internal override RdpPattern Compile (RelaxngGrammar grammar)
706 // RdpParamList rdpl = new RdpParamList ();
707 // foreach (RelaxngParam prm in this.paramList)
708 // rdpl.Add (prm.Compile (grammar));
709 RdpPattern p = null;
710 if (this.except != null) {
711 if (except.Patterns.Count == 0)
712 throw new RelaxngException ("data except pattern have no children.");
713 p = except.Patterns [0].Compile (grammar);
714 for (int i=1; i<except.Patterns.Count; i++)
715 p = new RdpChoice (p,
716 except.Patterns [i].Compile (grammar));
719 IsCompiled = true;
720 if (this.except != null)
721 return new RdpDataExcept (new RdpDatatype (DatatypeLibrary, Type, ParamList, grammar.Provider), p);
722 else
723 return new RdpData (new RdpDatatype (DatatypeLibrary, Type, ParamList, grammar.Provider));
726 internal override void CheckConstraints ()
728 CheckDatatypeName ();
732 public class RelaxngValue : RelaxngDataSupport
734 string value;
736 public override RelaxngPatternType PatternType {
737 get { return RelaxngPatternType.Value; }
740 public string Value {
741 get { return value; }
742 set { this.value = value; }
745 public override void Write (XmlWriter writer)
747 writer.WriteStartElement ("", "value", RelaxngGrammar.NamespaceURI);
748 if (Type != null) {
749 writer.WriteStartAttribute ("type", String.Empty);
750 if (DatatypeLibrary != null && DatatypeLibrary != String.Empty)
751 writer.WriteAttributeString ("xmlns", "data", "http://www.w3.org/2000/xmlns/", DatatypeLibrary);
752 writer.WriteQualifiedName (Type, DatatypeLibrary);
753 writer.WriteEndAttribute ();
755 writer.WriteString (Value);
756 writer.WriteEndElement ();
759 internal override RdpPattern Compile (RelaxngGrammar grammar)
761 IsCompiled = true;
762 return new RdpValue (new RdpDatatype (DatatypeLibrary,
763 Type, null, grammar.Provider), value);
766 internal override void CheckConstraints ()
768 CheckDatatypeName ();
772 public class RelaxngList : RelaxngSingleContentPattern
774 internal RelaxngList ()
778 public override RelaxngPatternType PatternType {
779 get { return RelaxngPatternType.List; }
782 public override void Write (XmlWriter writer)
784 writer.WriteStartElement ("", "list", RelaxngGrammar.NamespaceURI);
785 foreach (RelaxngPattern p in Patterns)
786 p.Write (writer);
787 writer.WriteEndElement ();
790 internal override RdpPattern Compile (RelaxngGrammar grammar)
793 IsCompiled = true;
794 return new RdpList (makeSingle (grammar));
797 internal override void CheckConstraints ()
799 // nothing to check
803 public class RelaxngElement : RelaxngSingleContentPattern
805 RelaxngNameClass nc;
807 public RelaxngElement ()
811 public RelaxngNameClass NameClass {
812 get { return nc; }
813 set { nc = value; }
816 public override RelaxngPatternType PatternType {
817 get { return RelaxngPatternType.Element; }
820 public override void Write (XmlWriter writer)
822 writer.WriteStartElement ("", "element", RelaxngGrammar.NamespaceURI);
823 nc.Write (writer);
824 foreach (RelaxngPattern p in Patterns)
825 p.Write (writer);
826 writer.WriteEndElement ();
829 internal override RdpPattern Compile (RelaxngGrammar grammar)
831 return new RdpElement (
832 nc.Compile (grammar), this.makeSingle (grammar));
835 internal override void CheckConstraints ()
837 NameClass.CheckConstraints (false, false);
839 foreach (RelaxngPattern p in Patterns)
840 p.CheckConstraints ();
844 public class RelaxngAttribute : RelaxngPattern
846 RelaxngNameClass nc;
847 RelaxngPattern p;
849 public RelaxngAttribute ()
853 public RelaxngPattern Pattern {
854 get { return p; }
855 set { p = value; }
858 public RelaxngNameClass NameClass {
859 get { return nc; }
860 set { nc = value; }
863 public override RelaxngPatternType PatternType {
864 get { return RelaxngPatternType.Attribute; }
867 public override void Write (XmlWriter writer)
869 writer.WriteStartElement ("", "attribute", RelaxngGrammar.NamespaceURI);
870 nc.Write (writer);
871 if (p != null)
872 p.Write (writer);
873 writer.WriteEndElement ();
876 private void checkInvalidAttrNameClass (RdpNameClass nc)
878 string xmlnsNS = "http://www.w3.org/2000/xmlns";
879 RdpNameClassChoice choice = nc as RdpNameClassChoice;
880 if (choice != null) {
881 checkInvalidAttrNameClass (choice.LValue);
882 checkInvalidAttrNameClass (choice.RValue);
883 return;
885 RdpAnyNameExcept except = nc as RdpAnyNameExcept;
886 if (except != null) {
887 checkInvalidAttrNameClass (except.ExceptNameClass);
888 return;
890 if (nc is RdpAnyName)
891 return;
893 RdpName n = nc as RdpName;
894 if (n != null) {
895 if (n.NamespaceURI == xmlnsNS)
896 throw new RelaxngException ("cannot specify \"" + xmlnsNS + "\" for name of attribute.");
897 if (n.LocalName == "xmlns" && n.NamespaceURI == "")
898 throw new RelaxngException ("cannot specify \"xmlns\" inside empty ns context.");
899 } else {
900 RdpNsName nn = nc as RdpNsName;
901 if (nn.NamespaceURI == "http://www.w3.org/2000/xmlns")
902 throw new RelaxngException ("cannot specify \"" + xmlnsNS + "\" for name of attribute.");
903 RdpNsNameExcept x = nc as RdpNsNameExcept;
904 if (x != null)
905 checkInvalidAttrNameClass (x.ExceptNameClass);
909 internal override RdpPattern Compile (RelaxngGrammar grammar)
911 IsCompiled = true;
912 RdpNameClass cnc = nc.Compile (grammar);
913 this.checkInvalidAttrNameClass (cnc);
915 return new RdpAttribute (cnc,
916 (p != null) ?
917 p.Compile (grammar) :
918 RdpText.Instance);
921 internal override void CheckConstraints ()
923 NameClass.CheckConstraints (false, false);
925 if (p != null)
926 p.CheckConstraints ();
930 internal class RdpUnresolvedRef : RdpPattern
932 string name;
933 // bool parentRef;
934 RelaxngGrammar targetGrammar;
935 RdpPattern referencedPattern;
937 public RdpUnresolvedRef (string name, RelaxngGrammar g)
939 this.name = name;
940 // this.parentRef = parentRef;
941 targetGrammar = g;
944 public string Name {
945 get { return name; }
946 set { name = value; }
949 public RdpPattern RefPattern {
950 get { return referencedPattern; }
951 set { referencedPattern = value; }
954 // public bool IsParentRef {
955 // get { return parentRef; }
956 // }
958 public RelaxngGrammar TargetGrammar {
959 get { return targetGrammar; }
962 public override RelaxngPatternType PatternType {
963 get { return RelaxngPatternType.Ref; }
966 public override RdpContentType ContentType {
967 get { return RdpContentType.Empty; }
971 public override bool Nullable {
972 get {
973 throw new InvalidOperationException ();
977 internal override RdpPattern ExpandRef (Hashtable defs)
979 return referencedPattern.ExpandRef (defs);
982 internal override void MarkReachableDefs ()
984 TargetGrammar.MarkReacheableDefine (this.name);
987 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
989 // throw new InvalidOperationException ();
992 internal override bool ContainsText ()
994 return false;
995 // throw new InvalidOperationException ();
999 public class RelaxngRef : RelaxngPattern
1001 string name;
1003 public RelaxngRef ()
1007 public string Name {
1008 get { return name; }
1009 set { name = value; }
1012 public override RelaxngPatternType PatternType {
1013 get { return RelaxngPatternType.Ref; }
1016 public override void Write (XmlWriter writer)
1018 writer.WriteStartElement ("", "ref", RelaxngGrammar.NamespaceURI);
1019 writer.WriteAttributeString ("name", name);
1020 writer.WriteEndElement ();
1023 internal override RdpPattern Compile (RelaxngGrammar grammar)
1025 // Important!! This compile method only generates stub.
1026 IsCompiled = false;
1027 return new RdpUnresolvedRef (name, grammar);
1030 internal override void CheckConstraints ()
1032 // nothing to check
1036 public class RelaxngParentRef : RelaxngPattern
1038 string name;
1040 public RelaxngParentRef ()
1044 public string Name {
1045 get { return name; }
1046 set { name = value; }
1049 public override RelaxngPatternType PatternType {
1050 get { return RelaxngPatternType.ParentRef; }
1053 public override void Write (XmlWriter writer)
1055 writer.WriteStartElement ("", "parentRef", RelaxngGrammar.NamespaceURI);
1056 writer.WriteAttributeString ("name", name);
1057 writer.WriteEndElement ();
1060 internal override RdpPattern Compile (RelaxngGrammar grammar)
1062 IsCompiled = false;
1063 return new RdpUnresolvedRef (name, grammar.ParentGrammar);
1066 internal override void CheckConstraints ()
1068 // nothing to check
1072 public class RelaxngExternalRef : RelaxngPattern
1074 string href;
1075 string ns;
1077 public RelaxngExternalRef ()
1081 public string Href {
1082 get { return href; }
1083 set { href = value; }
1086 public string NSContext {
1087 get { return ns; }
1088 set { ns = value; }
1091 public override RelaxngPatternType PatternType {
1092 get { return RelaxngPatternType.ExternalRef; }
1095 public override void Write (XmlWriter writer)
1097 writer.WriteStartElement ("", "externalRef", RelaxngGrammar.NamespaceURI);
1098 writer.WriteAttributeString ("href", Href);
1099 writer.WriteEndElement ();
1102 internal override RdpPattern Compile (RelaxngGrammar grammar)
1104 grammar.CheckIncludeRecursion (Href);
1105 grammar.IncludedUris.Add (Href, Href);
1106 if (grammar.Resolver == null)
1107 throw new RelaxngException ("To compile 'include' element, XmlResolver is required.");
1108 Uri uri = grammar.Resolver.ResolveUri (BaseUri != String.Empty ? new Uri (BaseUri) : null, Href);
1109 XmlTextReader xtr = null;
1110 try {
1111 xtr = new XmlTextReader (uri.AbsoluteUri, (Stream) grammar.Resolver.GetEntity (uri, null, typeof (Stream)));
1112 RelaxngReader r = new RelaxngReader (xtr, ns);
1113 r.MoveToContent ();
1114 RelaxngPattern p = r.ReadPattern ();
1115 p.DataProvider = grammar.Provider;
1117 RdpPattern ret = p.Compile (grammar);
1119 grammar.IncludedUris.Remove (Href);
1121 return ret;
1122 } finally {
1123 if (xtr != null)
1124 xtr.Close ();
1129 internal override void CheckConstraints ()
1131 // nothing to check
1135 public class RelaxngOneOrMore : RelaxngSingleContentPattern
1137 public RelaxngOneOrMore ()
1141 public override RelaxngPatternType PatternType {
1142 get { return RelaxngPatternType.OneOrMore; }
1145 public override void Write (XmlWriter writer)
1147 writer.WriteStartElement ("", "oneOrMore", RelaxngGrammar.NamespaceURI);
1148 foreach (RelaxngPattern p in Patterns)
1149 p.Write (writer);
1150 writer.WriteEndElement ();
1153 internal override RdpPattern Compile (RelaxngGrammar grammar)
1155 IsCompiled = true;
1156 return new RdpOneOrMore (makeSingle (grammar));
1160 public class RelaxngZeroOrMore : RelaxngSingleContentPattern
1162 public RelaxngZeroOrMore ()
1166 public override RelaxngPatternType PatternType {
1167 get { return RelaxngPatternType.ZeroOrMore; }
1170 public override void Write (XmlWriter writer)
1172 writer.WriteStartElement ("", "zeroOrMore", RelaxngGrammar.NamespaceURI);
1173 foreach (RelaxngPattern p in Patterns)
1174 p.Write (writer);
1175 writer.WriteEndElement ();
1178 internal override RdpPattern Compile (RelaxngGrammar grammar)
1180 IsCompiled = true;
1181 return new RdpChoice (
1182 new RdpOneOrMore (makeSingle (grammar)),
1183 RdpEmpty.Instance);
1187 public class RelaxngOptional : RelaxngSingleContentPattern
1189 public RelaxngOptional ()
1193 public override RelaxngPatternType PatternType {
1194 get { return RelaxngPatternType.Optional; }
1197 public override void Write (XmlWriter writer)
1199 writer.WriteStartElement ("", "optional", RelaxngGrammar.NamespaceURI);
1200 foreach (RelaxngPattern p in Patterns)
1201 p.Write (writer);
1202 writer.WriteEndElement ();
1205 internal override RdpPattern Compile (RelaxngGrammar grammar)
1207 IsCompiled = true;
1208 return new RdpChoice (
1209 makeSingle (grammar), RdpEmpty.Instance);
1213 public class RelaxngMixed : RelaxngSingleContentPattern
1215 public RelaxngMixed ()
1219 public override RelaxngPatternType PatternType {
1220 get { return RelaxngPatternType.Mixed; }
1223 public override void Write (XmlWriter writer)
1225 writer.WriteStartElement ("", "mixed", RelaxngGrammar.NamespaceURI);
1226 foreach (RelaxngPattern p in Patterns)
1227 p.Write (writer);
1228 writer.WriteEndElement ();
1231 internal override RdpPattern Compile (RelaxngGrammar grammar)
1233 IsCompiled = true;
1234 return new RdpInterleave (makeSingle (grammar), RdpText.Instance);
1238 public class RelaxngChoice : RelaxngBinaryContentPattern
1240 public RelaxngChoice ()
1244 public override RelaxngPatternType PatternType {
1245 get { return RelaxngPatternType.Choice; }
1248 public override void Write (XmlWriter writer)
1250 writer.WriteStartElement ("", "choice", RelaxngGrammar.NamespaceURI);
1251 foreach (RelaxngPattern p in Patterns)
1252 p.Write (writer);
1253 writer.WriteEndElement ();
1256 internal override RdpPattern Compile (RelaxngGrammar grammar)
1258 IsCompiled = true;
1259 return makeBinary (grammar);
1263 public class RelaxngGroup : RelaxngBinaryContentPattern
1265 public RelaxngGroup ()
1269 public override RelaxngPatternType PatternType {
1270 get { return RelaxngPatternType.Group; }
1273 public override void Write (XmlWriter writer)
1275 writer.WriteStartElement ("", "group", RelaxngGrammar.NamespaceURI);
1276 foreach (RelaxngPattern p in Patterns)
1277 p.Write (writer);
1278 writer.WriteEndElement ();
1281 internal override RdpPattern Compile (RelaxngGrammar grammar)
1283 IsCompiled = true;
1284 return makeBinary (grammar);
1288 public class RelaxngInterleave : RelaxngBinaryContentPattern
1290 public RelaxngInterleave ()
1294 public override RelaxngPatternType PatternType {
1295 get { return RelaxngPatternType.Interleave; }
1298 public override void Write (XmlWriter writer)
1300 writer.WriteStartElement ("", "interleave", RelaxngGrammar.NamespaceURI);
1301 foreach (RelaxngPattern p in Patterns)
1302 p.Write (writer);
1303 writer.WriteEndElement ();
1306 internal override RdpPattern Compile (RelaxngGrammar grammar)
1308 IsCompiled = true;
1309 return makeBinary (grammar);
1313 public class RelaxngParam : RelaxngElementBase
1315 string name;
1316 string value;
1318 public RelaxngParam ()
1322 public RelaxngParam (string name, string value)
1324 this.name = name;
1325 this.value = value;
1328 public string Name {
1329 get { return name; }
1330 set { name = value; }
1333 public string Value {
1334 get { return value; }
1335 set { this.value = value; }
1338 public override void Write (XmlWriter writer)
1340 writer.WriteStartElement ("", "param", RelaxngGrammar.NamespaceURI);
1341 writer.WriteAttributeString ("name", name);
1342 writer.WriteString (Value);
1343 writer.WriteEndElement ();
1346 internal RdpParam Compile (RelaxngGrammar grammar)
1348 IsCompiled = true;
1349 return new RdpParam (name, value);
1353 public class RelaxngParamList : CollectionBase
1355 public RelaxngParamList ()
1359 public void Add (RelaxngParam p)
1361 List.Add (p);
1364 public RelaxngParam this [int i] {
1365 get { return this.List [i] as RelaxngParam; }
1366 set { this.List [i] = value; }
1369 public void Insert (int pos, RelaxngParam p)
1371 List.Insert (pos, p);
1374 public void Remove (RelaxngParam p)
1376 List.Remove (p);
1380 public class RelaxngExcept : RelaxngElementBase
1382 RelaxngPatternList patterns = new RelaxngPatternList ();
1384 public RelaxngExcept ()
1388 public RelaxngPatternList Patterns {
1389 get { return patterns; }
1392 public override void Write (XmlWriter writer)
1394 writer.WriteStartElement ("", "except", RelaxngGrammar.NamespaceURI);
1395 foreach (RelaxngPattern p in Patterns)
1396 p.Write (writer);
1397 writer.WriteEndElement ();
1401 internal class RelaxngRefPattern
1403 RelaxngPattern patternRef;
1404 string name;
1406 // When we found ref, use it.
1407 public RelaxngRefPattern (string name)
1409 this.name = name;
1412 // When we found define, use it.
1413 public RelaxngRefPattern (RelaxngPattern patternRef)
1415 this.patternRef = patternRef;
1418 public string Name {
1419 get { return name; }
1422 public RelaxngPattern PatternRef {
1423 get { return patternRef; }
1424 set { patternRef = value; }
1427 #endregion