2 // Commons.Xml.Relaxng.RelaxngPattern.cs
5 // Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
7 // 2003 Atsushi Enomoto "No rights reserved."
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:
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
;
38 using Commons
.Xml
.Relaxng
.Derivative
;
39 using Commons
.Xml
.Relaxng
.Rnc
;
42 using NSResolver
= System
.Xml
.IXmlNamespaceResolver
;
44 using NSResolver
= System
.Xml
.XmlNamespaceManager
;
47 namespace Commons
.Xml
.Relaxng
49 #region Common abstract
50 public abstract class RelaxngElementBase
53 int lineNumber
, linePosition
;
56 internal bool IsCompiled
{
57 get { return isCompiled; }
58 set { isCompiled = value; }
61 public int LineNumber
{
62 get { return lineNumber; }
63 set { lineNumber = value; }
66 public int LinePosition
{
67 get { return linePosition; }
68 set { linePosition = value; }
71 public string BaseUri
{
72 get { return baseUri; }
73 set { baseUri = value; }
76 public abstract void Write (XmlWriter writer
);
78 internal abstract void WriteRnc (RncWriter writer
);
80 public RelaxngPattern
ReadExternalResource (RelaxngGrammar grammar
, Uri uri
, string nsContext
)
82 XmlTextReader xtr
= null;
83 RelaxngGrammar g
= null;
85 if (grammar
.IsSourceCompactSyntax
) {
86 return RncParser
.ParseRnc (new StreamReader ((Stream
) grammar
.Resolver
.GetEntity (uri
, null, typeof (Stream
))), null, BaseUri
, nsContext
);
88 xtr
= new XmlTextReader (uri
.AbsoluteUri
, (Stream
) grammar
.Resolver
.GetEntity (uri
, null, typeof (Stream
)));
89 RelaxngReader r
= new RelaxngReader (xtr
, nsContext
, grammar
.Resolver
);
91 return r
.ReadPattern ();
93 } catch (Exception ex
) { // umm, bad catch though :-(
94 throw new RelaxngException (this, String
.Format("Could not include grammar {0}: {1}", uri
.AbsoluteUri
, ex
.Message
), ex
);
102 public abstract class RelaxngSingleContentPattern
: RelaxngPattern
104 private RelaxngPatternList patterns
= new RelaxngPatternList ();
106 public RelaxngPatternList Patterns
{
107 get { return patterns; }
110 internal RdpPattern
makeSingle (RelaxngGrammar g
)
112 // Flatten patterns into RdpGroup. See 4.12.
113 if (patterns
.Count
== 0)
114 throw new RelaxngException (this, "No pattern contents.");
115 RdpPattern p
= ((RelaxngPattern
) patterns
[0]).Compile (g
);
116 if (patterns
.Count
== 1)
118 for (int i
=1; i
<patterns
.Count
; i
++) {
120 ((RelaxngPattern
) patterns
[i
]).Compile (g
));
125 internal override void CheckConstraints ()
127 foreach (RelaxngPattern p
in Patterns
)
128 p
.CheckConstraints ();
132 public abstract class RelaxngBinaryContentPattern
: RelaxngPattern
134 private RelaxngPatternList patterns
= new RelaxngPatternList ();
136 public RelaxngPatternList Patterns
{
137 get { return patterns; }
140 internal RdpPattern
makeBinary (RelaxngGrammar g
)
142 // Flatten patterns. See 4.12.
143 if (patterns
.Count
== 0)
144 throw new RelaxngException (this, "No pattern contents.");
146 RdpPattern p
= ((RelaxngPattern
) patterns
[0]).Compile (g
);
147 if (patterns
.Count
== 1)
150 for (int i
=1; i
<patterns
.Count
; i
++) {
152 ((RelaxngPattern
) patterns
[i
]).Compile (g
);
153 switch (this.PatternType
) {
154 case RelaxngPatternType
.Choice
:
155 p
= new RdpChoice (p
, cp
);
157 case RelaxngPatternType
.Group
:
158 p
= new RdpGroup (p
, cp
);
160 case RelaxngPatternType
.Interleave
:
161 p
= new RdpInterleave (p
, cp
);
169 internal override void CheckConstraints ()
171 foreach (RelaxngPattern p
in Patterns
)
172 p
.CheckConstraints ();
177 #region Grammatical elements
178 public interface IGrammarContent
182 public class RelaxngStart
: RelaxngElementBase
, IGrammarContent
187 public RelaxngStart ()
191 public string Combine
{
192 get { return combine; }
193 set { combine = value; }
196 public RelaxngPattern Pattern
{
201 public override void Write (XmlWriter writer
)
203 writer
.WriteStartElement ("", "start", RelaxngGrammar
.NamespaceURI
);
205 writer
.WriteAttributeString ("combine", combine
);
207 writer
.WriteEndElement ();
210 internal override void WriteRnc (RncWriter writer
)
212 writer
.WriteStart (this);
215 internal RdpPattern
Compile (RelaxngGrammar grammar
)
217 return p
.Compile (grammar
);
221 public class RelaxngDefine
: RelaxngElementBase
, IGrammarContent
224 private RelaxngPatternList patterns
= new RelaxngPatternList ();
227 public RelaxngDefine ()
231 public RelaxngPatternList Patterns
{
232 get { return patterns; }
235 public string Combine
{
236 get { return combine; }
237 set { combine = value; }
242 set { name = value; }
245 public override void Write (XmlWriter writer
)
247 writer
.WriteStartElement ("", "define", RelaxngGrammar
.NamespaceURI
);
248 writer
.WriteAttributeString ("name", name
);
250 writer
.WriteAttributeString ("combine", combine
);
251 foreach (RelaxngPattern p
in Patterns
)
253 writer
.WriteEndElement ();
256 internal override void WriteRnc (RncWriter writer
)
258 writer
.WriteDefine (this);
261 internal RdpPattern
Compile (RelaxngGrammar grammar
)
263 return makeSingle (grammar
);
266 private RdpPattern
makeSingle (RelaxngGrammar g
)
268 // Flatten patterns into RdpGroup. See 4.12.
269 if (patterns
.Count
== 0)
270 throw new RelaxngException (this, "No pattern contents.");
271 RdpPattern p
= ((RelaxngPattern
) patterns
[0]).Compile (g
);
272 if (patterns
.Count
== 1)
274 for (int i
=1; i
<patterns
.Count
; i
++) {
276 ((RelaxngPattern
) patterns
[i
]).Compile (g
));
282 public class RelaxngInclude
: RelaxngElementBase
, IGrammarContent
285 RelaxngGrammarContentList starts
= new RelaxngGrammarContentList ();
286 RelaxngGrammarContentList defines
= new RelaxngGrammarContentList ();
287 RelaxngGrammarContentList divs
= new RelaxngGrammarContentList ();
290 public RelaxngInclude ()
296 set { href = value; }
299 public RelaxngGrammarContentList Starts
{
300 get { return starts; }
303 public RelaxngGrammarContentList Defines
{
304 get { return defines; }
307 public RelaxngGrammarContentList Divs
{
311 public string NSContext
{
316 public override void Write (XmlWriter writer
)
318 writer
.WriteStartElement ("", "include", RelaxngGrammar
.NamespaceURI
);
319 writer
.WriteAttributeString ("href", href
);
320 foreach (RelaxngStart start
in Starts
)
321 start
.Write (writer
);
322 foreach (RelaxngDefine define
in Defines
)
323 define
.Write (writer
);
324 foreach (RelaxngDiv div
in Divs
)
326 writer
.WriteEndElement ();
329 internal override void WriteRnc (RncWriter writer
)
331 writer
.WriteInclude (this);
335 internal RelaxngDiv
Compile (RelaxngGrammar grammar
)
337 grammar
.CheckIncludeRecursion (Href
);
338 grammar
.IncludedUris
.Add (Href
, Href
);
339 if (grammar
.Resolver
== null)
340 throw new RelaxngException (this, "To compile 'include' element, XmlResolver is required.");
343 if (BaseUri
!= null && BaseUri
!= String
.Empty
)
344 baseUri
= new Uri (BaseUri
);
345 } catch (UriFormatException
) {
346 if (File
.Exists (BaseUri
))
347 baseUri
= new Uri (Path
.GetFullPath (BaseUri
));
349 Uri uri
= grammar
.Resolver
.ResolveUri (baseUri
, Href
);
351 RelaxngGrammar g
= ReadExternalResource (grammar
, uri
, (ns
!= null && ns
.Length
!= 0) || !grammar
.IsSourceCompactSyntax
? ns
: grammar
.DefaultNamespace
) as RelaxngGrammar
;
353 throw new RelaxngException (this, "Included syntax must start with \"grammar\" element.");
354 g
.DataProvider
= grammar
.Provider
;
355 g
.IsSourceCompactSyntax
= grammar
.IsSourceCompactSyntax
;
357 // process recursive inclusions.
358 foreach (RelaxngInclude inc
in g
.Includes
)
359 g
.Divs
.Add (inc
.Compile (grammar
));
361 // process this own div children.
362 // each div subelements are also compiled.
363 foreach (RelaxngDiv cdiv
in divs
)
365 foreach (RelaxngDiv cdiv
in g
.Divs
)
368 // replace redifinitions into div.
370 if (this.Starts
.Count
> 0 && g
.Starts
.Count
== 0)
371 throw new RelaxngException (this, "When the included grammar does not contain start components, this include component must not contain start components.");
372 RelaxngGrammarContentList appliedStarts
= (this.starts
.Count
> 0) ?
373 this.starts
: g
.Starts
;
375 RelaxngDiv div
= new RelaxngDiv ();
376 div
.BaseUri
= this.BaseUri
;
377 div
.LinePosition
= this.LinePosition
;
378 div
.LineNumber
= this.LineNumber
;
380 foreach (RelaxngStart start
in appliedStarts
)
381 div
.Starts
.Add (start
);
384 Hashtable overrides
= new Hashtable ();
385 Hashtable originalDefs
= new Hashtable ();
386 foreach (RelaxngDefine def
in defines
) {
387 overrides
.Add (def
.Name
, def
.Name
);
388 div
.Defines
.Add (def
);
390 foreach (RelaxngDefine def
in g
.Defines
) {
391 originalDefs
[def
.Name
] = def
.Name
;
392 if (!overrides
.ContainsKey (def
.Name
)) {
393 div
.Defines
.Add (def
);
398 foreach (string name
in overrides
.Values
)
399 if (!originalDefs
.ContainsKey (name
))
400 throw new RelaxngException (this, "The include component must not contain define components whose name does not appear in the included grammar component.");
402 grammar
.IncludedUris
.Remove (Href
);
407 public class RelaxngDiv
: RelaxngElementBase
, IGrammarContent
409 RelaxngGrammarContentList starts
= new RelaxngGrammarContentList ();
410 RelaxngGrammarContentList defines
= new RelaxngGrammarContentList ();
411 RelaxngGrammarContentList includes
= new RelaxngGrammarContentList ();
412 RelaxngGrammarContentList divs
= new RelaxngGrammarContentList ();
418 public RelaxngGrammarContentList Starts
{
419 get { return starts; }
422 public RelaxngGrammarContentList Defines
{
423 get { return defines; }
426 public RelaxngGrammarContentList Includes
{
427 get { return includes; }
430 public RelaxngGrammarContentList Divs
{
434 public override void Write (XmlWriter writer
)
436 writer
.WriteStartElement ("", "div", RelaxngGrammar
.NamespaceURI
);
437 foreach (RelaxngStart start
in Starts
)
438 start
.Write (writer
);
439 foreach (RelaxngDefine define
in Defines
)
440 define
.Write (writer
);
441 foreach (RelaxngInclude include
in Includes
)
442 include
.Write (writer
);
443 foreach (RelaxngDiv div
in Divs
)
445 writer
.WriteEndElement ();
448 internal override void WriteRnc (RncWriter writer
)
450 writer
.WriteDiv (this);
453 internal void Compile (RelaxngGrammar grammar
)
455 foreach (RelaxngDiv div
in divs
)
456 div
.Compile (grammar
);
457 foreach (RelaxngInclude inc
in includes
)
458 inc
.Compile (grammar
).Compile (grammar
); // compile compiled divs
459 foreach (RelaxngStart start
in starts
)
460 grammar
.Starts
.Add (start
);
461 foreach (RelaxngDefine define
in defines
)
462 grammar
.Defines
.Add (define
);
467 #region RelaxngPatterns
468 public abstract class RelaxngPattern
: RelaxngElementBase
472 public static RelaxngPattern
Read (XmlReader xmlReader
)
474 return Read (xmlReader
, null);
477 public static RelaxngPattern
Read (XmlReader xmlReader
, RelaxngDatatypeProvider provider
)
479 return Read (xmlReader
, provider
, new XmlUrlResolver ());
482 public static RelaxngPattern
Read (XmlReader xmlReader
, RelaxngDatatypeProvider provider
, XmlResolver xmlResolver
)
484 RelaxngReader r
= new RelaxngReader (xmlReader
, null, xmlResolver
);
485 if (r
.ReadState
== ReadState
.Initial
)
488 RelaxngPattern p
= r
.ReadPattern ();
489 p
.DataProvider
= provider
;
490 p
.XmlResolver
= xmlResolver
;
495 RdpPattern startRelaxngPattern
;
496 RelaxngDatatypeProvider provider
;
497 XmlResolver resolver
;
501 public XmlResolver XmlResolver
{
503 nullResolver
= value == null;
508 public abstract RelaxngPatternType PatternType { get; }
509 public RelaxngDatatypeProvider DataProvider
{
518 public void Compile ()
520 RelaxngGrammar g
= null;
521 if (this is RelaxngGrammar
)
522 g
= (RelaxngGrammar
) this;
524 g
= new RelaxngGrammar ();
525 g
.XmlResolver
= this.Resolver
;
526 g
.BaseUri
= this.BaseUri
;
527 g
.LineNumber
= this.LineNumber
;
528 g
.LinePosition
= this.LinePosition
;
529 RelaxngStart st
= new RelaxngStart ();
530 st
.BaseUri
= this.BaseUri
;
531 st
.LineNumber
= this.LineNumber
;
532 st
.LinePosition
= this.LinePosition
;
535 g
.Provider
= provider
;
537 startRelaxngPattern
= g
.Compile (null);
538 this.IsCompiled
= true;
541 public void WriteCompact (TextWriter writer
)
543 WriteCompact (new RncWriter (writer
));
546 public void WriteCompact (TextWriter writer
, NSResolver res
)
548 WriteCompact (new RncWriter (writer
, res
));
551 void WriteCompact (RncWriter writer
)
553 RelaxngGrammar g
= this as RelaxngGrammar
;
554 string ns
= (g
!= null ? g
.DefaultNamespace
: null);
555 writer
.WriteNamespaces (ns
);
560 internal XmlResolver Resolver
{
564 if (resolver
== null)
565 resolver
= new XmlUrlResolver ();
570 internal abstract void CheckConstraints ();
572 protected RelaxngPattern ()
576 internal abstract RdpPattern
Compile (RelaxngGrammar grammar
);
578 internal RdpPattern StartPattern
{
579 get { return startRelaxngPattern; }
583 public class RelaxngPatternList
: CollectionBase
585 public RelaxngPatternList ()
589 public void Add (RelaxngPattern p
)
594 public RelaxngPattern
this [int i
] {
595 get { return this.List [i] as RelaxngPattern; }
596 set { this.List [i] = value; }
599 public void Insert (int pos
, RelaxngPattern p
)
601 List
.Insert (pos
, p
);
604 public void Remove (RelaxngPattern p
)
610 public class RelaxngGrammarContentList
: CollectionBase
612 public RelaxngGrammarContentList ()
616 public void Add (IGrammarContent p
)
621 public IGrammarContent
this [int i
] {
622 get { return this.List [i] as IGrammarContent; }
623 set { this.List [i] = value; }
626 public void Insert (int pos
, IGrammarContent p
)
628 List
.Insert (pos
, p
);
631 public void Remove (IGrammarContent p
)
637 // strict to say, it's not a pattern ;)
638 public class RelaxngNotAllowed
: RelaxngPattern
640 public RelaxngNotAllowed ()
644 public override RelaxngPatternType PatternType
{
645 get { return RelaxngPatternType.NotAllowed; }
648 public override void Write (XmlWriter writer
)
650 writer
.WriteStartElement ("", "notAllowed", RelaxngGrammar
.NamespaceURI
);
651 writer
.WriteEndElement ();
654 internal override void WriteRnc (RncWriter writer
)
656 writer
.WriteNotAllowed (this);
659 internal override RdpPattern
Compile (RelaxngGrammar grammar
)
661 return RdpNotAllowed
.Instance
;
664 internal override void CheckConstraints ()
670 public class RelaxngEmpty
: RelaxngPattern
672 public RelaxngEmpty ()
676 public override RelaxngPatternType PatternType
{
677 get { return RelaxngPatternType.Empty; }
680 public override void Write (XmlWriter writer
)
682 writer
.WriteStartElement ("", "empty", RelaxngGrammar
.NamespaceURI
);
683 writer
.WriteEndElement ();
686 internal override void WriteRnc (RncWriter writer
)
688 writer
.WriteEmpty (this);
691 internal override RdpPattern
Compile (RelaxngGrammar grammar
)
693 return RdpEmpty
.Instance
;
696 internal override void CheckConstraints ()
702 public class RelaxngText
: RelaxngPattern
704 public RelaxngText ()
708 public override RelaxngPatternType PatternType
{
709 get { return RelaxngPatternType.Text; }
712 public override void Write (XmlWriter writer
)
714 writer
.WriteStartElement ("", "text", RelaxngGrammar
.NamespaceURI
);
715 writer
.WriteEndElement ();
718 internal override void WriteRnc (RncWriter writer
)
720 writer
.WriteText (this);
723 internal override RdpPattern
Compile (RelaxngGrammar grammar
)
725 return RdpText
.Instance
;
728 internal override void CheckConstraints ()
734 public abstract class RelaxngDataSupport
: RelaxngPattern
737 string datatypeLibrary
;
741 set { type = value; }
744 public string DatatypeLibrary
{
745 get { return datatypeLibrary; }
746 set { datatypeLibrary = value; }
749 internal void CheckDatatypeName ()
751 // Data type name check is done in RdpData(Except) derivative creation.
755 public class RelaxngData
: RelaxngDataSupport
757 RelaxngParamList paramList
= new RelaxngParamList ();
758 RelaxngExcept except
;
760 public RelaxngData ()
764 public override RelaxngPatternType PatternType
{
765 get { return RelaxngPatternType.Data; }
768 public RelaxngParamList ParamList
{
769 get { return paramList; }
772 public RelaxngExcept Except
{
773 get { return except; }
774 set { except = value; }
777 public override void Write (XmlWriter writer
)
779 writer
.WriteStartElement ("", "data", RelaxngGrammar
.NamespaceURI
);
780 if (DatatypeLibrary
!= null && DatatypeLibrary
!= String
.Empty
)
781 writer
.WriteAttributeString ("datatypeLibrary", DatatypeLibrary
);
782 writer
.WriteAttributeString ("type", Type
);
784 foreach (RelaxngParam p
in ParamList
)
788 Except
.Write (writer
);
790 writer
.WriteEndElement ();
793 internal override void WriteRnc (RncWriter writer
)
795 writer
.WriteData (this);
798 internal override RdpPattern
Compile (RelaxngGrammar grammar
)
800 // RdpParamList rdpl = new RdpParamList ();
801 // foreach (RelaxngParam prm in this.paramList)
802 // rdpl.Add (prm.Compile (grammar));
804 if (this.except
!= null) {
805 if (except
.Patterns
.Count
== 0)
806 throw new RelaxngException (this, "data except pattern have no children.");
807 p
= except
.Patterns
[0].Compile (grammar
);
808 for (int i
=1; i
<except
.Patterns
.Count
; i
++)
809 p
= new RdpChoice (p
,
810 except
.Patterns
[i
].Compile (grammar
));
814 if (this.except
!= null)
815 return new RdpDataExcept (new RdpDatatype (DatatypeLibrary
, Type
, ParamList
, grammar
.Provider
), p
);
817 return new RdpData (new RdpDatatype (DatatypeLibrary
, Type
, ParamList
, grammar
.Provider
));
820 internal override void CheckConstraints ()
822 CheckDatatypeName ();
826 public class RelaxngValue
: RelaxngDataSupport
830 public override RelaxngPatternType PatternType
{
831 get { return RelaxngPatternType.Value; }
834 public string Value
{
835 get { return value; }
836 set { this.value = value; }
839 public override void Write (XmlWriter writer
)
841 writer
.WriteStartElement ("", "value", RelaxngGrammar
.NamespaceURI
);
843 writer
.WriteStartAttribute ("type", String
.Empty
);
844 if (DatatypeLibrary
!= null && DatatypeLibrary
!= String
.Empty
)
845 writer
.WriteAttributeString ("datatypeLibrary", DatatypeLibrary
);
846 writer
.WriteAttributeString ("type", Type
);
848 writer
.WriteString (Value
);
849 writer
.WriteEndElement ();
852 internal override void WriteRnc (RncWriter writer
)
854 writer
.WriteValue (this);
857 internal override RdpPattern
Compile (RelaxngGrammar grammar
)
860 return new RdpValue (new RdpDatatype (DatatypeLibrary
,
861 Type
, null, grammar
.Provider
), value);
864 internal override void CheckConstraints ()
866 CheckDatatypeName ();
870 public class RelaxngList
: RelaxngSingleContentPattern
872 internal RelaxngList ()
876 public override RelaxngPatternType PatternType
{
877 get { return RelaxngPatternType.List; }
880 public override void Write (XmlWriter writer
)
882 writer
.WriteStartElement ("", "list", RelaxngGrammar
.NamespaceURI
);
883 foreach (RelaxngPattern p
in Patterns
)
885 writer
.WriteEndElement ();
888 internal override void WriteRnc (RncWriter writer
)
890 writer
.WriteList (this);
893 internal override RdpPattern
Compile (RelaxngGrammar grammar
)
897 return new RdpList (makeSingle (grammar
));
900 internal override void CheckConstraints ()
906 public class RelaxngElement
: RelaxngSingleContentPattern
910 public RelaxngElement ()
914 public RelaxngNameClass NameClass
{
919 public override RelaxngPatternType PatternType
{
920 get { return RelaxngPatternType.Element; }
923 public override void Write (XmlWriter writer
)
925 writer
.WriteStartElement ("", "element", RelaxngGrammar
.NamespaceURI
);
927 foreach (RelaxngPattern p
in Patterns
)
929 writer
.WriteEndElement ();
932 internal override void WriteRnc (RncWriter writer
)
934 writer
.WriteElement (this);
937 internal override RdpPattern
Compile (RelaxngGrammar grammar
)
939 return new RdpElement (
940 nc
.Compile (grammar
), this.makeSingle (grammar
));
943 internal override void CheckConstraints ()
945 NameClass
.CheckConstraints (false, false);
947 foreach (RelaxngPattern p
in Patterns
)
948 p
.CheckConstraints ();
952 public class RelaxngAttribute
: RelaxngPattern
957 public RelaxngAttribute ()
961 public RelaxngPattern Pattern
{
966 public RelaxngNameClass NameClass
{
971 public override RelaxngPatternType PatternType
{
972 get { return RelaxngPatternType.Attribute; }
975 public override void Write (XmlWriter writer
)
977 writer
.WriteStartElement ("", "attribute", RelaxngGrammar
.NamespaceURI
);
981 writer
.WriteEndElement ();
984 internal override void WriteRnc (RncWriter writer
)
986 writer
.WriteAttribute (this);
989 private void checkInvalidAttrNameClass (RdpNameClass nc
)
991 string xmlnsNS
= "http://www.w3.org/2000/xmlns";
992 RdpNameClassChoice choice
= nc
as RdpNameClassChoice
;
993 if (choice
!= null) {
994 checkInvalidAttrNameClass (choice
.LValue
);
995 checkInvalidAttrNameClass (choice
.RValue
);
998 RdpAnyNameExcept except
= nc
as RdpAnyNameExcept
;
999 if (except
!= null) {
1000 checkInvalidAttrNameClass (except
.ExceptNameClass
);
1003 if (nc
is RdpAnyName
)
1006 RdpName n
= nc
as RdpName
;
1008 if (n
.NamespaceURI
== xmlnsNS
)
1009 throw new RelaxngException (this, "cannot specify \"" + xmlnsNS
+ "\" for name of attribute.");
1010 if (n
.LocalName
== "xmlns" && n
.NamespaceURI
== "")
1011 throw new RelaxngException (this, "cannot specify \"xmlns\" inside empty ns context.");
1013 RdpNsName nn
= nc
as RdpNsName
;
1014 if (nn
.NamespaceURI
== "http://www.w3.org/2000/xmlns")
1015 throw new RelaxngException (this, "cannot specify \"" + xmlnsNS
+ "\" for name of attribute.");
1016 RdpNsNameExcept x
= nc
as RdpNsNameExcept
;
1018 checkInvalidAttrNameClass (x
.ExceptNameClass
);
1022 internal override RdpPattern
Compile (RelaxngGrammar grammar
)
1025 RdpNameClass cnc
= nc
.Compile (grammar
);
1026 this.checkInvalidAttrNameClass (cnc
);
1028 return new RdpAttribute (cnc
,
1030 p
.Compile (grammar
) :
1034 internal override void CheckConstraints ()
1036 NameClass
.CheckConstraints (false, false);
1039 p
.CheckConstraints ();
1043 internal class RdpUnresolvedRef
: RdpPattern
1047 RelaxngGrammar targetGrammar
;
1048 RdpPattern referencedPattern
;
1050 public RdpUnresolvedRef (string name
, RelaxngGrammar g
)
1053 // this.parentRef = parentRef;
1057 public string Name
{
1058 get { return name; }
1059 set { name = value; }
1062 public RdpPattern RefPattern
{
1063 get { return referencedPattern; }
1064 set { referencedPattern = value; }
1067 // public bool IsParentRef {
1068 // get { return parentRef; }
1071 public RelaxngGrammar TargetGrammar
{
1072 get { return targetGrammar; }
1075 public override RelaxngPatternType PatternType
{
1076 get { return RelaxngPatternType.Ref; }
1079 public override RdpContentType ContentType
{
1080 get { return RdpContentType.Empty; }
1084 public override bool Nullable
{
1086 throw new InvalidOperationException ("Internal error: should not reach.");
1090 public override void GetLabels (Hashtable elements
, Hashtable attributes
, bool collectNameClass
)
1092 // Now it could reach (CheckNameOverlap) so comment out here.
1093 // throw new InvalidOperationException ("Internal error: should not reach.");
1096 internal override RdpPattern
ExpandRef (Hashtable defs
)
1098 return referencedPattern
.ExpandRef (defs
);
1101 internal override void MarkReachableDefs ()
1103 TargetGrammar
.MarkReacheableDefine (this.name
);
1106 internal override RdpPattern
ReduceEmptyAndNotAllowed (ref bool result
, Hashtable visited
)
1109 referencedPattern
.ReduceEmptyAndNotAllowed (
1110 ref result
, visited
);
1114 internal override void CheckConstraints (bool attribute
, bool oneOrMore
, bool oneOrMoreGroup
, bool oneOrMoreInterleave
, bool list
, bool dataExcept
)
1116 // throw new InvalidOperationException ();
1119 internal override bool ContainsText ()
1122 // throw new InvalidOperationException ();
1126 public class RelaxngRef
: RelaxngPattern
1130 public RelaxngRef ()
1134 public string Name
{
1135 get { return name; }
1136 set { name = value; }
1139 public override RelaxngPatternType PatternType
{
1140 get { return RelaxngPatternType.Ref; }
1143 public override void Write (XmlWriter writer
)
1145 writer
.WriteStartElement ("", "ref", RelaxngGrammar
.NamespaceURI
);
1146 writer
.WriteAttributeString ("name", name
);
1147 writer
.WriteEndElement ();
1150 internal override void WriteRnc (RncWriter writer
)
1152 writer
.WriteRef (this);
1155 internal override RdpPattern
Compile (RelaxngGrammar grammar
)
1157 // Important!! This compile method only generates stub.
1159 return new RdpUnresolvedRef (name
, grammar
);
1162 internal override void CheckConstraints ()
1168 public class RelaxngParentRef
: RelaxngPattern
1172 public RelaxngParentRef ()
1176 public string Name
{
1177 get { return name; }
1178 set { name = value; }
1181 public override RelaxngPatternType PatternType
{
1182 get { return RelaxngPatternType.ParentRef; }
1185 public override void Write (XmlWriter writer
)
1187 writer
.WriteStartElement ("", "parentRef", RelaxngGrammar
.NamespaceURI
);
1188 writer
.WriteAttributeString ("name", name
);
1189 writer
.WriteEndElement ();
1192 internal override void WriteRnc (RncWriter writer
)
1194 writer
.WriteParentRef (this);
1197 internal override RdpPattern
Compile (RelaxngGrammar grammar
)
1200 return new RdpUnresolvedRef (name
, grammar
.ParentGrammar
);
1203 internal override void CheckConstraints ()
1209 public class RelaxngExternalRef
: RelaxngPattern
1214 public RelaxngExternalRef ()
1218 public string Href
{
1219 get { return href; }
1220 set { href = value; }
1223 public string NSContext
{
1228 public override RelaxngPatternType PatternType
{
1229 get { return RelaxngPatternType.ExternalRef; }
1232 public override void Write (XmlWriter writer
)
1234 writer
.WriteStartElement ("", "externalRef", RelaxngGrammar
.NamespaceURI
);
1235 writer
.WriteAttributeString ("href", Href
);
1236 writer
.WriteEndElement ();
1239 internal override void WriteRnc (RncWriter writer
)
1241 writer
.WriteExternalRef (this);
1244 internal override RdpPattern
Compile (RelaxngGrammar grammar
)
1246 grammar
.CheckIncludeRecursion (Href
);
1247 grammar
.IncludedUris
.Add (Href
, Href
);
1248 if (grammar
.Resolver
== null)
1249 throw new RelaxngException (this, "To compile 'include' element, XmlResolver is required.");
1250 Uri uri
= grammar
.Resolver
.ResolveUri (BaseUri
!= String
.Empty
? new Uri (BaseUri
) : null, Href
);
1251 RelaxngPattern p
= ReadExternalResource (grammar
, uri
, ns
);
1253 p
.DataProvider
= grammar
.Provider
;
1254 RdpPattern ret
= p
.Compile (grammar
);
1256 grammar
.IncludedUris
.Remove (Href
);
1262 internal override void CheckConstraints ()
1268 public class RelaxngOneOrMore
: RelaxngSingleContentPattern
1270 public RelaxngOneOrMore ()
1274 public override RelaxngPatternType PatternType
{
1275 get { return RelaxngPatternType.OneOrMore; }
1278 public override void Write (XmlWriter writer
)
1280 writer
.WriteStartElement ("", "oneOrMore", RelaxngGrammar
.NamespaceURI
);
1281 foreach (RelaxngPattern p
in Patterns
)
1283 writer
.WriteEndElement ();
1286 internal override void WriteRnc (RncWriter writer
)
1288 writer
.WriteOneOrMore (this);
1291 internal override RdpPattern
Compile (RelaxngGrammar grammar
)
1294 return new RdpOneOrMore (makeSingle (grammar
));
1298 public class RelaxngZeroOrMore
: RelaxngSingleContentPattern
1300 public RelaxngZeroOrMore ()
1304 public override RelaxngPatternType PatternType
{
1305 get { return RelaxngPatternType.ZeroOrMore; }
1308 public override void Write (XmlWriter writer
)
1310 writer
.WriteStartElement ("", "zeroOrMore", RelaxngGrammar
.NamespaceURI
);
1311 foreach (RelaxngPattern p
in Patterns
)
1313 writer
.WriteEndElement ();
1316 internal override void WriteRnc (RncWriter writer
)
1318 writer
.WriteZeroOrMore (this);
1321 internal override RdpPattern
Compile (RelaxngGrammar grammar
)
1324 return new RdpChoice (
1325 new RdpOneOrMore (makeSingle (grammar
)),
1330 public class RelaxngOptional
: RelaxngSingleContentPattern
1332 public RelaxngOptional ()
1336 public override RelaxngPatternType PatternType
{
1337 get { return RelaxngPatternType.Optional; }
1340 public override void Write (XmlWriter writer
)
1342 writer
.WriteStartElement ("", "optional", RelaxngGrammar
.NamespaceURI
);
1343 foreach (RelaxngPattern p
in Patterns
)
1345 writer
.WriteEndElement ();
1348 internal override void WriteRnc (RncWriter writer
)
1350 writer
.WriteOptional (this);
1353 internal override RdpPattern
Compile (RelaxngGrammar grammar
)
1356 return new RdpChoice (
1357 makeSingle (grammar
), RdpEmpty
.Instance
);
1361 public class RelaxngMixed
: RelaxngSingleContentPattern
1363 public RelaxngMixed ()
1367 public override RelaxngPatternType PatternType
{
1368 get { return RelaxngPatternType.Mixed; }
1371 public override void Write (XmlWriter writer
)
1373 writer
.WriteStartElement ("", "mixed", RelaxngGrammar
.NamespaceURI
);
1374 foreach (RelaxngPattern p
in Patterns
)
1376 writer
.WriteEndElement ();
1379 internal override void WriteRnc (RncWriter writer
)
1381 writer
.WriteMixed (this);
1384 internal override RdpPattern
Compile (RelaxngGrammar grammar
)
1387 return new RdpInterleave (makeSingle (grammar
), RdpText
.Instance
);
1391 public class RelaxngChoice
: RelaxngBinaryContentPattern
1393 public RelaxngChoice ()
1397 public override RelaxngPatternType PatternType
{
1398 get { return RelaxngPatternType.Choice; }
1401 public override void Write (XmlWriter writer
)
1403 writer
.WriteStartElement ("", "choice", RelaxngGrammar
.NamespaceURI
);
1404 foreach (RelaxngPattern p
in Patterns
)
1406 writer
.WriteEndElement ();
1409 internal override void WriteRnc (RncWriter writer
)
1411 writer
.WriteChoice (this);
1414 internal override RdpPattern
Compile (RelaxngGrammar grammar
)
1417 return makeBinary (grammar
);
1421 public class RelaxngGroup
: RelaxngBinaryContentPattern
1423 public RelaxngGroup ()
1427 public override RelaxngPatternType PatternType
{
1428 get { return RelaxngPatternType.Group; }
1431 public override void Write (XmlWriter writer
)
1433 writer
.WriteStartElement ("", "group", RelaxngGrammar
.NamespaceURI
);
1434 foreach (RelaxngPattern p
in Patterns
)
1436 writer
.WriteEndElement ();
1439 internal override void WriteRnc (RncWriter writer
)
1441 writer
.WriteGroup (this);
1444 internal override RdpPattern
Compile (RelaxngGrammar grammar
)
1447 return makeBinary (grammar
);
1451 public class RelaxngInterleave
: RelaxngBinaryContentPattern
1453 public RelaxngInterleave ()
1457 public override RelaxngPatternType PatternType
{
1458 get { return RelaxngPatternType.Interleave; }
1461 public override void Write (XmlWriter writer
)
1463 writer
.WriteStartElement ("", "interleave", RelaxngGrammar
.NamespaceURI
);
1464 foreach (RelaxngPattern p
in Patterns
)
1466 writer
.WriteEndElement ();
1469 internal override void WriteRnc (RncWriter writer
)
1471 writer
.WriteInterleave (this);
1474 internal override RdpPattern
Compile (RelaxngGrammar grammar
)
1477 return makeBinary (grammar
);
1481 public class RelaxngParam
: RelaxngElementBase
1486 public RelaxngParam ()
1490 public RelaxngParam (string name
, string value)
1496 public string Name
{
1497 get { return name; }
1498 set { name = value; }
1501 public string Value
{
1502 get { return value; }
1503 set { this.value = value; }
1506 public override void Write (XmlWriter writer
)
1508 writer
.WriteStartElement ("", "param", RelaxngGrammar
.NamespaceURI
);
1509 writer
.WriteAttributeString ("name", name
);
1510 writer
.WriteString (Value
);
1511 writer
.WriteEndElement ();
1514 internal override void WriteRnc (RncWriter writer
)
1516 writer
.WriteParam (this);
1519 internal RdpParam
Compile (RelaxngGrammar grammar
)
1522 return new RdpParam (name
, value);
1526 public class RelaxngParamList
: CollectionBase
1528 public RelaxngParamList ()
1532 public void Add (RelaxngParam p
)
1537 public RelaxngParam
this [int i
] {
1538 get { return this.List [i] as RelaxngParam; }
1539 set { this.List [i] = value; }
1542 public void Insert (int pos
, RelaxngParam p
)
1544 List
.Insert (pos
, p
);
1547 public void Remove (RelaxngParam p
)
1553 public class RelaxngExcept
: RelaxngElementBase
1555 RelaxngPatternList patterns
= new RelaxngPatternList ();
1557 public RelaxngExcept ()
1561 public RelaxngPatternList Patterns
{
1562 get { return patterns; }
1565 public override void Write (XmlWriter writer
)
1567 writer
.WriteStartElement ("", "except", RelaxngGrammar
.NamespaceURI
);
1568 foreach (RelaxngPattern p
in Patterns
)
1570 writer
.WriteEndElement ();
1573 internal override void WriteRnc (RncWriter writer
)
1575 writer
.WriteDataExcept (this);
1579 internal class RelaxngRefPattern
1581 RelaxngPattern patternRef
;
1584 // When we found ref, use it.
1585 public RelaxngRefPattern (string name
)
1590 // When we found define, use it.
1591 public RelaxngRefPattern (RelaxngPattern patternRef
)
1593 this.patternRef
= patternRef
;
1596 public string Name
{
1597 get { return name; }
1600 public RelaxngPattern PatternRef
{
1601 get { return patternRef; }
1602 set { patternRef = value; }