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 WriteRnc (new RncWriter (writer));
\r
518 public void WriteCompact (TextWriter writer, NSResolver res)
\r
520 WriteRnc (new RncWriter (writer, res));
\r
524 internal XmlResolver Resolver {
\r
528 if (resolver == null)
\r
529 resolver = new XmlUrlResolver ();
\r
534 internal abstract void CheckConstraints ();
\r
536 protected RelaxngPattern ()
\r
540 internal abstract RdpPattern Compile (RelaxngGrammar grammar);
\r
542 internal RdpPattern StartPattern {
\r
543 get { return startRelaxngPattern; }
\r
547 public class RelaxngPatternList : CollectionBase
\r
549 public RelaxngPatternList ()
\r
553 public void Add (RelaxngPattern p)
\r
558 public RelaxngPattern this [int i] {
\r
559 get { return this.List [i] as RelaxngPattern; }
\r
560 set { this.List [i] = value; }
\r
563 public void Insert (int pos, RelaxngPattern p)
\r
565 List.Insert (pos, p);
\r
568 public void Remove (RelaxngPattern p)
\r
574 public class RelaxngGrammarContentList : CollectionBase
\r
576 public RelaxngGrammarContentList ()
\r
580 public void Add (IGrammarContent p)
\r
585 public IGrammarContent this [int i] {
\r
586 get { return this.List [i] as IGrammarContent; }
\r
587 set { this.List [i] = value; }
\r
590 public void Insert (int pos, IGrammarContent p)
\r
592 List.Insert (pos, p);
\r
595 public void Remove (IGrammarContent p)
\r
601 // strict to say, it's not a pattern ;)
\r
602 public class RelaxngNotAllowed : RelaxngPattern
\r
604 public RelaxngNotAllowed ()
\r
608 public override RelaxngPatternType PatternType {
\r
609 get { return RelaxngPatternType.NotAllowed; }
\r
612 public override void Write (XmlWriter writer)
\r
614 writer.WriteStartElement ("", "notAllowed", RelaxngGrammar.NamespaceURI);
\r
615 writer.WriteEndElement ();
\r
618 internal override void WriteRnc (RncWriter writer)
\r
620 writer.WriteNotAllowed (this);
\r
623 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
625 return RdpNotAllowed.Instance;
\r
628 internal override void CheckConstraints ()
\r
630 // nothing to check
\r
634 public class RelaxngEmpty : RelaxngPattern
\r
636 public RelaxngEmpty ()
\r
640 public override RelaxngPatternType PatternType {
\r
641 get { return RelaxngPatternType.Empty; }
\r
644 public override void Write (XmlWriter writer)
\r
646 writer.WriteStartElement ("", "empty", RelaxngGrammar.NamespaceURI);
\r
647 writer.WriteEndElement ();
\r
650 internal override void WriteRnc (RncWriter writer)
\r
652 writer.WriteEmpty (this);
\r
655 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
657 return RdpEmpty.Instance;
\r
660 internal override void CheckConstraints ()
\r
662 // nothing to check
\r
666 public class RelaxngText : RelaxngPattern
\r
668 public RelaxngText ()
\r
672 public override RelaxngPatternType PatternType {
\r
673 get { return RelaxngPatternType.Text; }
\r
676 public override void Write (XmlWriter writer)
\r
678 writer.WriteStartElement ("", "text", RelaxngGrammar.NamespaceURI);
\r
679 writer.WriteEndElement ();
\r
682 internal override void WriteRnc (RncWriter writer)
\r
684 writer.WriteText (this);
\r
687 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
689 return RdpText.Instance;
\r
692 internal override void CheckConstraints ()
\r
694 // nothing to check
\r
698 public abstract class RelaxngDataSupport : RelaxngPattern
\r
701 string datatypeLibrary;
\r
703 public string Type {
\r
704 get { return type; }
\r
705 set { type = value; }
\r
708 public string DatatypeLibrary {
\r
709 get { return datatypeLibrary; }
\r
710 set { datatypeLibrary = value; }
\r
713 internal void CheckDatatypeName ()
\r
715 // Data type name check is done in RdpData(Except) derivative creation.
\r
719 public class RelaxngData : RelaxngDataSupport
\r
721 RelaxngParamList paramList = new RelaxngParamList ();
\r
722 RelaxngExcept except;
\r
724 public RelaxngData ()
\r
728 public override RelaxngPatternType PatternType {
\r
729 get { return RelaxngPatternType.Data; }
\r
732 public RelaxngParamList ParamList {
\r
733 get { return paramList; }
\r
736 public RelaxngExcept Except {
\r
737 get { return except; }
\r
738 set { except = value; }
\r
741 public override void Write (XmlWriter writer)
\r
743 writer.WriteStartElement ("", "data", RelaxngGrammar.NamespaceURI);
\r
744 if (DatatypeLibrary != null && DatatypeLibrary != String.Empty)
\r
745 writer.WriteAttributeString ("xmlns", "data", "http://www.w3.org/2000/xmlns/", DatatypeLibrary);
\r
746 writer.WriteStartAttribute ("type", String.Empty);
\r
747 writer.WriteQualifiedName (Type, DatatypeLibrary);
\r
748 writer.WriteEndAttribute ();
\r
750 foreach (RelaxngParam p in ParamList)
\r
753 if (Except != null)
\r
754 Except.Write (writer);
\r
756 writer.WriteEndElement ();
\r
759 internal override void WriteRnc (RncWriter writer)
\r
761 writer.WriteData (this);
\r
764 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
766 // RdpParamList rdpl = new RdpParamList ();
\r
767 // foreach (RelaxngParam prm in this.paramList)
\r
768 // rdpl.Add (prm.Compile (grammar));
\r
769 RdpPattern p = null;
\r
770 if (this.except != null) {
\r
771 if (except.Patterns.Count == 0)
\r
772 throw new RelaxngException (this, "data except pattern have no children.");
\r
773 p = except.Patterns [0].Compile (grammar);
\r
774 for (int i=1; i<except.Patterns.Count; i++)
\r
775 p = new RdpChoice (p,
\r
776 except.Patterns [i].Compile (grammar));
\r
780 if (this.except != null)
\r
781 return new RdpDataExcept (new RdpDatatype (DatatypeLibrary, Type, ParamList, grammar.Provider), p);
\r
783 return new RdpData (new RdpDatatype (DatatypeLibrary, Type, ParamList, grammar.Provider));
\r
786 internal override void CheckConstraints ()
\r
788 CheckDatatypeName ();
\r
792 public class RelaxngValue : RelaxngDataSupport
\r
796 public override RelaxngPatternType PatternType {
\r
797 get { return RelaxngPatternType.Value; }
\r
800 public string Value {
\r
801 get { return value; }
\r
802 set { this.value = value; }
\r
805 public override void Write (XmlWriter writer)
\r
807 writer.WriteStartElement ("", "value", RelaxngGrammar.NamespaceURI);
\r
808 if (Type != null) {
\r
809 writer.WriteStartAttribute ("type", String.Empty);
\r
810 if (DatatypeLibrary != null && DatatypeLibrary != String.Empty)
\r
811 writer.WriteAttributeString ("xmlns", "data", "http://www.w3.org/2000/xmlns/", DatatypeLibrary);
\r
812 writer.WriteQualifiedName (Type, DatatypeLibrary);
\r
813 writer.WriteEndAttribute ();
\r
815 writer.WriteString (Value);
\r
816 writer.WriteEndElement ();
\r
819 internal override void WriteRnc (RncWriter writer)
\r
821 writer.WriteValue (this);
\r
824 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
827 return new RdpValue (new RdpDatatype (DatatypeLibrary,
\r
828 Type, null, grammar.Provider), value);
\r
831 internal override void CheckConstraints ()
\r
833 CheckDatatypeName ();
\r
837 public class RelaxngList : RelaxngSingleContentPattern
\r
839 internal RelaxngList ()
\r
843 public override RelaxngPatternType PatternType {
\r
844 get { return RelaxngPatternType.List; }
\r
847 public override void Write (XmlWriter writer)
\r
849 writer.WriteStartElement ("", "list", RelaxngGrammar.NamespaceURI);
\r
850 foreach (RelaxngPattern p in Patterns)
\r
852 writer.WriteEndElement ();
\r
855 internal override void WriteRnc (RncWriter writer)
\r
857 writer.WriteList (this);
\r
860 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
864 return new RdpList (makeSingle (grammar));
\r
867 internal override void CheckConstraints ()
\r
869 // nothing to check
\r
873 public class RelaxngElement : RelaxngSingleContentPattern
\r
875 RelaxngNameClass nc;
\r
877 public RelaxngElement ()
\r
881 public RelaxngNameClass NameClass {
\r
883 set { nc = value; }
\r
886 public override RelaxngPatternType PatternType {
\r
887 get { return RelaxngPatternType.Element; }
\r
890 public override void Write (XmlWriter writer)
\r
892 writer.WriteStartElement ("", "element", RelaxngGrammar.NamespaceURI);
\r
894 foreach (RelaxngPattern p in Patterns)
\r
896 writer.WriteEndElement ();
\r
899 internal override void WriteRnc (RncWriter writer)
\r
901 writer.WriteElement (this);
\r
904 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
906 return new RdpElement (
\r
907 nc.Compile (grammar), this.makeSingle (grammar));
\r
910 internal override void CheckConstraints ()
\r
912 NameClass.CheckConstraints (false, false);
\r
914 foreach (RelaxngPattern p in Patterns)
\r
915 p.CheckConstraints ();
\r
919 public class RelaxngAttribute : RelaxngPattern
\r
921 RelaxngNameClass nc;
\r
924 public RelaxngAttribute ()
\r
928 public RelaxngPattern Pattern {
\r
933 public RelaxngNameClass NameClass {
\r
935 set { nc = value; }
\r
938 public override RelaxngPatternType PatternType {
\r
939 get { return RelaxngPatternType.Attribute; }
\r
942 public override void Write (XmlWriter writer)
\r
944 writer.WriteStartElement ("", "attribute", RelaxngGrammar.NamespaceURI);
\r
948 writer.WriteEndElement ();
\r
951 internal override void WriteRnc (RncWriter writer)
\r
953 writer.WriteAttribute (this);
\r
956 private void checkInvalidAttrNameClass (RdpNameClass nc)
\r
958 string xmlnsNS = "http://www.w3.org/2000/xmlns";
\r
959 RdpNameClassChoice choice = nc as RdpNameClassChoice;
\r
960 if (choice != null) {
\r
961 checkInvalidAttrNameClass (choice.LValue);
\r
962 checkInvalidAttrNameClass (choice.RValue);
\r
965 RdpAnyNameExcept except = nc as RdpAnyNameExcept;
\r
966 if (except != null) {
\r
967 checkInvalidAttrNameClass (except.ExceptNameClass);
\r
970 if (nc is RdpAnyName)
\r
973 RdpName n = nc as RdpName;
\r
975 if (n.NamespaceURI == xmlnsNS)
\r
976 throw new RelaxngException (this, "cannot specify \"" + xmlnsNS + "\" for name of attribute.");
\r
977 if (n.LocalName == "xmlns" && n.NamespaceURI == "")
\r
978 throw new RelaxngException (this, "cannot specify \"xmlns\" inside empty ns context.");
\r
980 RdpNsName nn = nc as RdpNsName;
\r
981 if (nn.NamespaceURI == "http://www.w3.org/2000/xmlns")
\r
982 throw new RelaxngException (this, "cannot specify \"" + xmlnsNS + "\" for name of attribute.");
\r
983 RdpNsNameExcept x = nc as RdpNsNameExcept;
\r
985 checkInvalidAttrNameClass (x.ExceptNameClass);
\r
989 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
992 RdpNameClass cnc = nc.Compile (grammar);
\r
993 this.checkInvalidAttrNameClass (cnc);
\r
995 return new RdpAttribute (cnc,
\r
997 p.Compile (grammar) :
\r
1001 internal override void CheckConstraints ()
\r
1003 NameClass.CheckConstraints (false, false);
\r
1006 p.CheckConstraints ();
\r
1010 internal class RdpUnresolvedRef : RdpPattern
\r
1013 // bool parentRef;
\r
1014 RelaxngGrammar targetGrammar;
\r
1015 RdpPattern referencedPattern;
\r
1017 public RdpUnresolvedRef (string name, RelaxngGrammar g)
\r
1020 // this.parentRef = parentRef;
\r
1021 targetGrammar = g;
\r
1024 public string Name {
\r
1025 get { return name; }
\r
1026 set { name = value; }
\r
1029 public RdpPattern RefPattern {
\r
1030 get { return referencedPattern; }
\r
1031 set { referencedPattern = value; }
\r
1034 // public bool IsParentRef {
\r
1035 // get { return parentRef; }
\r
1038 public RelaxngGrammar TargetGrammar {
\r
1039 get { return targetGrammar; }
\r
1042 public override RelaxngPatternType PatternType {
\r
1043 get { return RelaxngPatternType.Ref; }
\r
1046 public override RdpContentType ContentType {
\r
1047 get { return RdpContentType.Empty; }
\r
1051 public override bool Nullable {
\r
1053 throw new InvalidOperationException ("Internal error: should not reach.");
\r
1057 public override void GetLabels (Hashtable elements, Hashtable attributes)
\r
1059 throw new InvalidOperationException ("Internal error: should not reach.");
\r
1062 internal override RdpPattern ExpandRef (Hashtable defs)
\r
1064 return referencedPattern.ExpandRef (defs);
\r
1067 internal override void MarkReachableDefs ()
\r
1069 TargetGrammar.MarkReacheableDefine (this.name);
\r
1072 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
\r
1074 // throw new InvalidOperationException ();
\r
1077 internal override bool ContainsText ()
\r
1080 // throw new InvalidOperationException ();
\r
1084 public class RelaxngRef : RelaxngPattern
\r
1088 public RelaxngRef ()
\r
1092 public string Name {
\r
1093 get { return name; }
\r
1094 set { name = value; }
\r
1097 public override RelaxngPatternType PatternType {
\r
1098 get { return RelaxngPatternType.Ref; }
\r
1101 public override void Write (XmlWriter writer)
\r
1103 writer.WriteStartElement ("", "ref", RelaxngGrammar.NamespaceURI);
\r
1104 writer.WriteAttributeString ("name", name);
\r
1105 writer.WriteEndElement ();
\r
1108 internal override void WriteRnc (RncWriter writer)
\r
1110 writer.WriteRef (this);
\r
1113 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1115 // Important!! This compile method only generates stub.
\r
1116 IsCompiled = false;
\r
1117 return new RdpUnresolvedRef (name, grammar);
\r
1120 internal override void CheckConstraints ()
\r
1122 // nothing to check
\r
1126 public class RelaxngParentRef : RelaxngPattern
\r
1130 public RelaxngParentRef ()
\r
1134 public string Name {
\r
1135 get { return name; }
\r
1136 set { name = value; }
\r
1139 public override RelaxngPatternType PatternType {
\r
1140 get { return RelaxngPatternType.ParentRef; }
\r
1143 public override void Write (XmlWriter writer)
\r
1145 writer.WriteStartElement ("", "parentRef", RelaxngGrammar.NamespaceURI);
\r
1146 writer.WriteAttributeString ("name", name);
\r
1147 writer.WriteEndElement ();
\r
1150 internal override void WriteRnc (RncWriter writer)
\r
1152 writer.WriteParentRef (this);
\r
1155 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1157 IsCompiled = false;
\r
1158 return new RdpUnresolvedRef (name, grammar.ParentGrammar);
\r
1161 internal override void CheckConstraints ()
\r
1163 // nothing to check
\r
1167 public class RelaxngExternalRef : RelaxngPattern
\r
1172 public RelaxngExternalRef ()
\r
1176 public string Href {
\r
1177 get { return href; }
\r
1178 set { href = value; }
\r
1181 public string NSContext {
\r
1182 get { return ns; }
\r
1183 set { ns = value; }
\r
1186 public override RelaxngPatternType PatternType {
\r
1187 get { return RelaxngPatternType.ExternalRef; }
\r
1190 public override void Write (XmlWriter writer)
\r
1192 writer.WriteStartElement ("", "externalRef", RelaxngGrammar.NamespaceURI);
\r
1193 writer.WriteAttributeString ("href", Href);
\r
1194 writer.WriteEndElement ();
\r
1197 internal override void WriteRnc (RncWriter writer)
\r
1199 writer.WriteExternalRef (this);
\r
1202 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1204 grammar.CheckIncludeRecursion (Href);
\r
1205 grammar.IncludedUris.Add (Href, Href);
\r
1206 if (grammar.Resolver == null)
\r
1207 throw new RelaxngException (this, "To compile 'include' element, XmlResolver is required.");
\r
1208 Uri uri = grammar.Resolver.ResolveUri (BaseUri != String.Empty ? new Uri (BaseUri) : null, Href);
\r
1209 XmlTextReader xtr = null;
\r
1211 xtr = new XmlTextReader (uri.AbsoluteUri, (Stream) grammar.Resolver.GetEntity (uri, null, typeof (Stream)));
\r
1212 RelaxngReader r = new RelaxngReader (xtr, ns);
\r
1213 r.MoveToContent ();
\r
1214 RelaxngPattern p = r.ReadPattern ();
\r
1215 p.DataProvider = grammar.Provider;
\r
1217 RdpPattern ret = p.Compile (grammar);
\r
1219 grammar.IncludedUris.Remove (Href);
\r
1229 internal override void CheckConstraints ()
\r
1231 // nothing to check
\r
1235 public class RelaxngOneOrMore : RelaxngSingleContentPattern
\r
1237 public RelaxngOneOrMore ()
\r
1241 public override RelaxngPatternType PatternType {
\r
1242 get { return RelaxngPatternType.OneOrMore; }
\r
1245 public override void Write (XmlWriter writer)
\r
1247 writer.WriteStartElement ("", "oneOrMore", RelaxngGrammar.NamespaceURI);
\r
1248 foreach (RelaxngPattern p in Patterns)
\r
1250 writer.WriteEndElement ();
\r
1253 internal override void WriteRnc (RncWriter writer)
\r
1255 writer.WriteOneOrMore (this);
\r
1258 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1260 IsCompiled = true;
\r
1261 return new RdpOneOrMore (makeSingle (grammar));
\r
1265 public class RelaxngZeroOrMore : RelaxngSingleContentPattern
\r
1267 public RelaxngZeroOrMore ()
\r
1271 public override RelaxngPatternType PatternType {
\r
1272 get { return RelaxngPatternType.ZeroOrMore; }
\r
1275 public override void Write (XmlWriter writer)
\r
1277 writer.WriteStartElement ("", "zeroOrMore", RelaxngGrammar.NamespaceURI);
\r
1278 foreach (RelaxngPattern p in Patterns)
\r
1280 writer.WriteEndElement ();
\r
1283 internal override void WriteRnc (RncWriter writer)
\r
1285 writer.WriteZeroOrMore (this);
\r
1288 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1290 IsCompiled = true;
\r
1291 return new RdpChoice (
\r
1292 new RdpOneOrMore (makeSingle (grammar)),
\r
1293 RdpEmpty.Instance);
\r
1297 public class RelaxngOptional : RelaxngSingleContentPattern
\r
1299 public RelaxngOptional ()
\r
1303 public override RelaxngPatternType PatternType {
\r
1304 get { return RelaxngPatternType.Optional; }
\r
1307 public override void Write (XmlWriter writer)
\r
1309 writer.WriteStartElement ("", "optional", RelaxngGrammar.NamespaceURI);
\r
1310 foreach (RelaxngPattern p in Patterns)
\r
1312 writer.WriteEndElement ();
\r
1315 internal override void WriteRnc (RncWriter writer)
\r
1317 writer.WriteOptional (this);
\r
1320 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1322 IsCompiled = true;
\r
1323 return new RdpChoice (
\r
1324 makeSingle (grammar), RdpEmpty.Instance);
\r
1328 public class RelaxngMixed : RelaxngSingleContentPattern
\r
1330 public RelaxngMixed ()
\r
1334 public override RelaxngPatternType PatternType {
\r
1335 get { return RelaxngPatternType.Mixed; }
\r
1338 public override void Write (XmlWriter writer)
\r
1340 writer.WriteStartElement ("", "mixed", RelaxngGrammar.NamespaceURI);
\r
1341 foreach (RelaxngPattern p in Patterns)
\r
1343 writer.WriteEndElement ();
\r
1346 internal override void WriteRnc (RncWriter writer)
\r
1348 writer.WriteMixed (this);
\r
1351 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1353 IsCompiled = true;
\r
1354 return new RdpInterleave (makeSingle (grammar), RdpText.Instance);
\r
1358 public class RelaxngChoice : RelaxngBinaryContentPattern
\r
1360 public RelaxngChoice ()
\r
1364 public override RelaxngPatternType PatternType {
\r
1365 get { return RelaxngPatternType.Choice; }
\r
1368 public override void Write (XmlWriter writer)
\r
1370 writer.WriteStartElement ("", "choice", RelaxngGrammar.NamespaceURI);
\r
1371 foreach (RelaxngPattern p in Patterns)
\r
1373 writer.WriteEndElement ();
\r
1376 internal override void WriteRnc (RncWriter writer)
\r
1378 writer.WriteChoice (this);
\r
1381 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1383 IsCompiled = true;
\r
1384 return makeBinary (grammar);
\r
1388 public class RelaxngGroup : RelaxngBinaryContentPattern
\r
1390 public RelaxngGroup ()
\r
1394 public override RelaxngPatternType PatternType {
\r
1395 get { return RelaxngPatternType.Group; }
\r
1398 public override void Write (XmlWriter writer)
\r
1400 writer.WriteStartElement ("", "group", RelaxngGrammar.NamespaceURI);
\r
1401 foreach (RelaxngPattern p in Patterns)
\r
1403 writer.WriteEndElement ();
\r
1406 internal override void WriteRnc (RncWriter writer)
\r
1408 writer.WriteGroup (this);
\r
1411 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1413 IsCompiled = true;
\r
1414 return makeBinary (grammar);
\r
1418 public class RelaxngInterleave : RelaxngBinaryContentPattern
\r
1420 public RelaxngInterleave ()
\r
1424 public override RelaxngPatternType PatternType {
\r
1425 get { return RelaxngPatternType.Interleave; }
\r
1428 public override void Write (XmlWriter writer)
\r
1430 writer.WriteStartElement ("", "interleave", RelaxngGrammar.NamespaceURI);
\r
1431 foreach (RelaxngPattern p in Patterns)
\r
1433 writer.WriteEndElement ();
\r
1436 internal override void WriteRnc (RncWriter writer)
\r
1438 writer.WriteInterleave (this);
\r
1441 internal override RdpPattern Compile (RelaxngGrammar grammar)
\r
1443 IsCompiled = true;
\r
1444 return makeBinary (grammar);
\r
1448 public class RelaxngParam : RelaxngElementBase
\r
1453 public RelaxngParam ()
\r
1457 public RelaxngParam (string name, string value)
\r
1460 this.value = value;
\r
1463 public string Name {
\r
1464 get { return name; }
\r
1465 set { name = value; }
\r
1468 public string Value {
\r
1469 get { return value; }
\r
1470 set { this.value = value; }
\r
1473 public override void Write (XmlWriter writer)
\r
1475 writer.WriteStartElement ("", "param", RelaxngGrammar.NamespaceURI);
\r
1476 writer.WriteAttributeString ("name", name);
\r
1477 writer.WriteString (Value);
\r
1478 writer.WriteEndElement ();
\r
1481 internal override void WriteRnc (RncWriter writer)
\r
1483 writer.WriteParam (this);
\r
1486 internal RdpParam Compile (RelaxngGrammar grammar)
\r
1488 IsCompiled = true;
\r
1489 return new RdpParam (name, value);
\r
1493 public class RelaxngParamList : CollectionBase
\r
1495 public RelaxngParamList ()
\r
1499 public void Add (RelaxngParam p)
\r
1504 public RelaxngParam this [int i] {
\r
1505 get { return this.List [i] as RelaxngParam; }
\r
1506 set { this.List [i] = value; }
\r
1509 public void Insert (int pos, RelaxngParam p)
\r
1511 List.Insert (pos, p);
\r
1514 public void Remove (RelaxngParam p)
\r
1520 public class RelaxngExcept : RelaxngElementBase
\r
1522 RelaxngPatternList patterns = new RelaxngPatternList ();
\r
1524 public RelaxngExcept ()
\r
1528 public RelaxngPatternList Patterns {
\r
1529 get { return patterns; }
\r
1532 public override void Write (XmlWriter writer)
\r
1534 writer.WriteStartElement ("", "except", RelaxngGrammar.NamespaceURI);
\r
1535 foreach (RelaxngPattern p in Patterns)
\r
1537 writer.WriteEndElement ();
\r
1540 internal override void WriteRnc (RncWriter writer)
\r
1542 writer.WriteDataExcept (this);
\r
1546 internal class RelaxngRefPattern
\r
1548 RelaxngPattern patternRef;
\r
1551 // When we found ref, use it.
\r
1552 public RelaxngRefPattern (string name)
\r
1557 // When we found define, use it.
\r
1558 public RelaxngRefPattern (RelaxngPattern patternRef)
\r
1560 this.patternRef = patternRef;
\r
1563 public string Name {
\r
1564 get { return name; }
\r
1567 public RelaxngPattern PatternRef {
\r
1568 get { return patternRef; }
\r
1569 set { patternRef = value; }
\r