2 // System.Xml.Schema.XmlSchemaGroupBase.cs
5 // Dwivedi, Ajay kumar Adwiv@Yahoo.com
6 // Atsushi Enomoto ginga@kit.hi-ho.ne.jp
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System
.Collections
;
32 using System
.Xml
.Serialization
;
34 namespace System
.Xml
.Schema
37 /// Summary description for XmlSchemaGroupRef.
39 public class XmlSchemaGroupRef
: XmlSchemaParticle
41 private XmlSchema schema
;
42 private XmlQualifiedName refName
;
43 const string xmlname
= "group";
44 private XmlSchemaGroup referencedGroup
;
46 public XmlSchemaGroupRef()
48 refName
= XmlQualifiedName
.Empty
;
52 [System
.Xml
.Serialization
.XmlAttribute("ref")]
53 public XmlQualifiedName RefName
55 get{ return refName; }
56 set{ refName = value; }
59 // Post Compilation Schema Information
61 public XmlSchemaGroupBase Particle
64 if (TargetGroup
!= null)
65 return TargetGroup
.Particle
;
71 internal XmlSchemaGroup TargetGroup
74 if (referencedGroup
!= null && referencedGroup
.IsCircularDefinition
)
77 return referencedGroup
;
82 /// 1. RefName must be present
84 internal override int Compile(ValidationEventHandler h
, XmlSchema schema
)
86 // If this is already compiled this time, simply skip.
87 if (this.IsComplied (schema
.CompilationId
))
91 XmlSchemaUtil
.CompileID(Id
,this,schema
.IDCollection
,h
);
92 CompileOccurence (h
, schema
);
94 if(refName
== null || refName
.IsEmpty
)
96 error(h
,"ref must be present");
98 else if(!XmlSchemaUtil
.CheckQName(RefName
))
99 error(h
, "RefName must be a valid XmlQualifiedName");
101 this.CompilationId
= schema
.CompilationId
;
105 internal override int Validate(ValidationEventHandler h
, XmlSchema schema
)
107 if (IsValidated (schema
.ValidationId
))
110 referencedGroup
= schema
.Groups
[RefName
] as XmlSchemaGroup
;
111 // it might be missing sub components.
112 if (referencedGroup
== null) {
113 if (!schema
.IsNamespaceAbsent (RefName
.Namespace
))
114 error (h
, "Referenced group " + RefName
+ " was not found in the corresponding schema.");
116 // See Errata E1-26: minOccurs=0 is now allowed.
117 else if (referencedGroup
.Particle
is XmlSchemaAll
&& ValidatedMaxOccurs
!= 1)
118 error (h
, "Group reference to -all- particle must have schema component {maxOccurs}=1.");
119 if (TargetGroup
!= null)
120 TargetGroup
.Validate (h
, schema
);
122 ValidationId
= schema
.ValidationId
;
126 bool busy
; // only for avoiding infinite loop on illegal recursion cases.
127 internal override XmlSchemaParticle
GetOptimizedParticle (bool isTop
)
130 return XmlSchemaParticle
.Empty
;
131 if (OptimizedParticle
!= null)
132 return OptimizedParticle
;
134 XmlSchemaGroup g
= referencedGroup
!= null ? referencedGroup
: schema
.Groups
[RefName
] as XmlSchemaGroup
;
135 if (g
!= null && g
.Particle
!= null) {
136 OptimizedParticle
= g
.Particle
;
137 OptimizedParticle
= OptimizedParticle
.GetOptimizedParticle (isTop
);
138 if (OptimizedParticle
!= XmlSchemaParticle
.Empty
&& (ValidatedMinOccurs
!= 1 || ValidatedMaxOccurs
!= 1)) {
139 OptimizedParticle
= OptimizedParticle
.GetShallowClone ();
140 OptimizedParticle
.MinOccurs
= this.MinOccurs
;
141 OptimizedParticle
.MaxOccurs
= this.MaxOccurs
;
142 OptimizedParticle
.CompileOccurence (null, null);
146 OptimizedParticle
= XmlSchemaParticle
.Empty
;
148 return OptimizedParticle
;
152 internal override bool ParticleEquals (XmlSchemaParticle other
)
154 return this.GetOptimizedParticle (true).ParticleEquals (other
);
157 internal override bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle
,
158 ValidationEventHandler h
, XmlSchema schema
, bool raiseError
)
160 if (TargetGroup
!= null)
161 return TargetGroup
.Particle
.ValidateDerivationByRestriction (baseParticle
, h
, schema
, raiseError
);
163 return false; // should not occur
167 internal override void CheckRecursion (int depth
, ValidationEventHandler h
, XmlSchema schema
)
169 if (TargetGroup
== null)
172 if (this.recursionDepth
== -1) {
173 recursionDepth
= depth
;
174 TargetGroup
.Particle
.CheckRecursion (depth
, h
, schema
);
176 } else if (depth
== recursionDepth
)
177 throw new XmlSchemaException ("Circular group reference was found.", this, null);
180 internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames
, ArrayList nsNames
,
181 ValidationEventHandler h
, XmlSchema schema
)
183 if (TargetGroup
!= null)
184 TargetGroup
.Particle
.ValidateUniqueParticleAttribution (qnames
, nsNames
, h
, schema
);
187 internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels
,
188 ValidationEventHandler h
, XmlSchema schema
)
190 if (TargetGroup
!= null)
191 TargetGroup
.Particle
.ValidateUniqueTypeAttribution (labels
, h
, schema
);
200 // maxOccurs = ? : 1>
201 // Content: (annotation?)
203 internal static XmlSchemaGroupRef
Read(XmlSchemaReader reader
, ValidationEventHandler h
)
205 XmlSchemaGroupRef groupref
= new XmlSchemaGroupRef();
206 reader
.MoveToElement();
208 if(reader
.NamespaceURI
!= XmlSchema
.Namespace
|| reader
.LocalName
!= xmlname
)
210 error(h
,"Should not happen :1: XmlSchemaGroup.Read, name="+reader
.Name
,null);
215 groupref
.LineNumber
= reader
.LineNumber
;
216 groupref
.LinePosition
= reader
.LinePosition
;
217 groupref
.SourceUri
= reader
.BaseURI
;
219 while(reader
.MoveToNextAttribute())
221 if(reader
.Name
== "id")
223 groupref
.Id
= reader
.Value
;
225 else if(reader
.Name
== "ref")
228 groupref
.refName
= XmlSchemaUtil
.ReadQNameAttribute(reader
,out innerex
);
230 error(h
, reader
.Value
+ " is not a valid value for ref attribute",innerex
);
232 else if(reader
.Name
== "maxOccurs")
236 groupref
.MaxOccursString
= reader
.Value
;
240 error(h
,reader
.Value
+ " is an invalid value for maxOccurs",e
);
243 else if(reader
.Name
== "minOccurs")
247 groupref
.MinOccursString
= reader
.Value
;
251 error(h
,reader
.Value
+ " is an invalid value for minOccurs", e
);
254 else if((reader
.NamespaceURI
== "" && reader
.Name
!= "xmlns") || reader
.NamespaceURI
== XmlSchema
.Namespace
)
256 error(h
,reader
.Name
+ " is not a valid attribute for group",null);
260 XmlSchemaUtil
.ReadUnhandledAttribute(reader
,groupref
);
264 reader
.MoveToElement();
265 if(reader
.IsEmptyElement
)
268 // Content: (annotation?)
270 while(reader
.ReadNextElement())
272 if(reader
.NodeType
== XmlNodeType
.EndElement
)
274 if(reader
.LocalName
!= xmlname
)
275 error(h
,"Should not happen :2: XmlSchemaGroupRef.Read, name="+reader
.Name
,null);
278 if(level
<= 1 && reader
.LocalName
== "annotation")
280 level
= 2; //Only one annotation
281 XmlSchemaAnnotation annotation
= XmlSchemaAnnotation
.Read(reader
,h
);
282 if(annotation
!= null)
283 groupref
.Annotation
= annotation
;
286 reader
.RaiseInvalidElementError();