浏览代码

2003-09-30 Atsushi Enomoto <[email protected]>

	* Forgot to append 8/24/2003 ChangeLog.
	* BUGS.txt, BUGS-MS.txt : Appended additional bug info.
	* BuiltInDatatype.cs, ValidationHandler.cs, XmlSchema.cs,
	  XmlSchemaAll.cs, XmlSchemaAnnotation.cs. XmlSchemaAny.cs,
	  XmlSchemaAnyAttribute.cs, XmlSchemaAttribute.cs,
	  XmlSchemaAttributeGroup.cs, XmlSchemaAttributeGroupRef.cs,
	  XmlSchemaChoice.cs, XmlSchemaCollection.cs,
	  XmlSchemaComplexContent.cs, XmlSchemaComplexContentExtension.cs,
	  XmlSchemaComplexContentRestriction.cs, XmlSchemaComplexType.cs,
	  XmlSchemaContent.cs, XmlSchemaDatatype.cs, XmlSchemaElement.cs,
	  XmlSchemaException.cs, XmlSchemaGroup.cs, XmlSchemaGroupBase.cs,
	  XmlSchemaGroupRef.cs, XmlSchemaIdentityConstraint.cs,
	  XmlSchemaKey.cs, XmlSchemaKeyref.cs, XmlSchemaNotation.cs,
	  XmlSchemaObject.cs, XmlSchemaObjectTable.cs, XmlSchemaParticle.cs,
	  XmlSchemaReader.cs, XmlSchemaSequence.cs, XmlSchemaSimpleContent.cs,
	  XmlSchemaSimpleContentExtension.cs,
	  XmlSchemaSimpleContentRestriction.cs, XmlSchemaSimpleType.cs,
	  XmlSchemaSimpleTypeContent.cs, XmlSchemaSimpleTypeList.cs,
	  XmlSchemaSimpleTypeRestriction.cs, XmlSchemaSimpleTypeUnion.cs,
	  XmlSchemaType.cs, XmlSchemaUnique.cs, XmlSchemaUtil.cs,
	  XmlSchemaXPath.cs :

	  - Almost all classes are changed to implement schema component
	    constraints, and schema validation using XsdValidatingReader.
	  - better exception messages.
	  - More datatype support.
	  and so on.

svn path=/trunk/mcs/; revision=18444
Atsushi Eno 22 年之前
父节点
当前提交
c62c061680
共有 47 个文件被更改,包括 3778 次插入672 次删除
  1. 104 4
      mcs/class/System.XML/System.Xml.Schema/BUGS-MS.txt
  2. 1 0
      mcs/class/System.XML/System.Xml.Schema/BUGS.txt
  3. 282 27
      mcs/class/System.XML/System.Xml.Schema/BuiltInDatatype.cs
  4. 36 0
      mcs/class/System.XML/System.Xml.Schema/ChangeLog
  5. 17 2
      mcs/class/System.XML/System.Xml.Schema/ValidationHandler.cs
  6. 148 182
      mcs/class/System.XML/System.Xml.Schema/XmlSchema.cs
  7. 103 6
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaAll.cs
  8. 2 2
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaAnnotation.cs
  9. 114 34
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaAny.cs
  10. 94 34
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaAnyAttribute.cs
  11. 134 48
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaAttribute.cs
  12. 64 10
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaAttributeGroup.cs
  13. 2 2
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaAttributeGroupRef.cs
  14. 109 26
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaChoice.cs
  15. 74 10
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaCollection.cs
  16. 22 4
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaComplexContent.cs
  17. 34 5
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaComplexContentExtension.cs
  18. 23 5
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaComplexContentRestriction.cs
  19. 556 67
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaComplexType.cs
  20. 7 0
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaContent.cs
  21. 30 3
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaDatatype.cs
  22. 378 56
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaElement.cs
  23. 27 7
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaException.cs
  24. 39 4
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaGroup.cs
  25. 8 0
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaGroupBase.cs
  26. 86 9
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaGroupRef.cs
  27. 28 6
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaIdentityConstraint.cs
  28. 3 11
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaKey.cs
  29. 22 6
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaKeyref.cs
  30. 2 2
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaNotation.cs
  31. 62 9
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaObject.cs
  32. 10 1
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaObjectTable.cs
  33. 120 2
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaParticle.cs
  34. 5 0
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaReader.cs
  35. 141 26
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaSequence.cs
  36. 16 4
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleContent.cs
  37. 42 5
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleContentExtension.cs
  38. 37 3
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleContentRestriction.cs
  39. 205 15
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleType.cs
  40. 26 0
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleTypeContent.cs
  41. 33 2
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleTypeList.cs
  42. 8 2
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleTypeRestriction.cs
  43. 49 2
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleTypeUnion.cs
  44. 22 9
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaType.cs
  45. 4 7
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaUnique.cs
  46. 206 12
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaUtil.cs
  47. 243 1
      mcs/class/System.XML/System.Xml.Schema/XmlSchemaXPath.cs

+ 104 - 4
mcs/class/System.XML/System.Xml.Schema/BUGS-MS.txt

@@ -1,12 +1,12 @@
 BUGS in MS Implementation of XmlSchema:
 
-1. Does not allow duplicate values in lists for final* and block* attributes. 
+001. Does not allow duplicate values in lists for final* and block* attributes. 
    For example "restriction restriction" is not allowed even though its a valid
    value for blockDefault.
 
-2. Resets the minOccurs to 0 if maxOccurs="0", whereas it should raise an error.
+002. Resets the minOccurs to 0 if maxOccurs="0", whereas it should raise an error.
 
-3. Allows abstract="true" in the a localElement whereas it is not allowed.
+003. Allows abstract="true" in the a localElement whereas it is not allowed.
 	<?xml version="1.0"?>
 	<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://xsdtesting" xmlns:x="http://xsdtesting" elementFormDefault="qualified">
 		<xsd:element name="doc">
@@ -17,4 +17,104 @@ BUGS in MS Implementation of XmlSchema:
 				</xsd:sequence>
 			</xsd:complexType>
 		</xsd:element>
-	</xsd:schema>
+	</xsd:schema>
+
+004. QName value constraint
+
+	When xs:QName based type is specified to an attribute or element
+	declaration, MS.NET fails to fill their {value constraints} (i.e.
+	default or fixed value), even though they have those namespace 
+	declaration by XmlSerializerNamespaces.
+
+005.  derivation by extension of xs:all
+
+	As it is discussed on w3c xmlschema-dev ML, MS System.Xml.Schema
+	incorrectly allows <complexType><complexContent><extension><all>
+	(i.e. XmlSchemaComplexContentExtension that contains XmlSchemaAll)
+	whose base type contains non-empty particle. It is prohibited, 
+	because, as XML Schema structures 3.4.2 (complex content Schema
+	Component) {content type} 2.3, complex content extension creates 
+	merged particles as a sequence, which never allows 'all' model group 
+	as its content. 
+	See: http://lists.w3.org/Archives/Public/xmlschema-dev/2002Oct/0156.html
+
+	Below are incorrect W3C test suite in msxsdtest/complexType: ctH013.xsd,
+	ctH019.xsd, ctH020.xsd, ctH021.xsd, ctH022.xsd, ctH023.xsd, ctJ001.xsd
+	and in msxsdtest/ModelGroups: mgA016.xsd, mgO007.xsd (9 testcases).
+
+006. xs:all minOccurs="0" not allowed
+
+	W3C WXS Structures REC. says that model group xs:all is limited to have
+	minOccurs=maxOccurs=1 in case of complexType's content type particle
+	(see 3.8.6 All Group Limited), but this is corrected to allow 
+	minOccurs=0. 
+	(see E1-26 of http://www.w3.org/2001/05/xmlschema-errata#Errata1)
+
+	Related msxsdtest is ParticlesEa022.xsd
+
+007. Insufficient unique particle attribution of xs:any
+
+	MS.NET allows <xs:choice><xs:any /><xs:element ... /></xs:choice>.
+
+	Related msxsdtests are: ParticlesJd002.xsd, ParticlesJd003.xsd and
+	ParticlesJd004.xsd. 
+	ParticlesIb001.xsd is also related, but it is not necessarily said as
+	incorrect. Both elements are of the same type, so *in a sense* they are
+	the same declaration. MSV, XSV and I stands different.
+
+008. Occurence Range OK (3.9.6) incorrectly assessed
+
+	Particles that have maxOccurs="0" looks simply ignored *before*
+	evaluating particle restriction valid, but it might get incorrect
+	result. For example, it is regarded as valid (while 'e1' must occur 1
+	time for the base 'bar' type):
+
+	<xsd:complexType name="foo">
+	<xsd:complexContent>
+	<xsd:restriction base="bar">
+		<xsd:choice>
+			<xsd:element name="e1" minOccurs="0" maxOccurs="0"/>
+			<xsd:element name="e2"/>
+		</xsd:choice>
+	</xsd:restriction>
+	</xsd:complexContent>
+	</xsd:complexType>
+
+	<xsd:complexType name="bar">
+	<xsd:choice>
+		<xsd:element name="e1"/>
+		<xsd:element name="e2"/>
+	</xsd:choice>
+	</xsd:complexType>
+
+	Related msxsdtest is mgH014.xsd.
+
+009. derived list incorrectly allowed
+
+	"Type Derivation OK" by list simple type of atomic simple type is
+	incorrectly assessed, when the list's {item type definition} (not 
+	{base type definition} ) can be assessed as "Type Derivation OK". MSV,
+	XSV and Xerces is not designed to allow such type derivation, and I
+	think they are more correct than MS. That is, MS's schema engine is
+	designed to use such schema typed class like:
+
+	     public class Foo { int notAList; }
+
+	Normally validates such xml into this class:
+
+	     <Foo>1</Foo>
+
+	MS validator consequently allows such instance like:
+
+	     <foo xsi:type="int_list_type">1 2 3</foo>
+
+	But it cannot be validated into that class Foo.
+
+	Related msxsdtests are elemT015.xsd and elemT022.xsd.
+
+010. derived union incorrectly allowed
+
+	Similar problem to No.9 above resides in xs:union. Derived union type
+	from atomic type is not naturally allowed.
+
+	Related msxsdtest is elemT014.xsd.

+ 1 - 0
mcs/class/System.XML/System.Xml.Schema/BUGS.txt

@@ -3,3 +3,4 @@ Bugs in Implementation:
 // None of the XmlSchemaObjects except the XmlSchema populate XmlSerializerNamespaces.
 //2. Non schema attributes are not being handled. Need an internal XmlAttribute constructor.
 //3. Documentation and appInfo's Markup is not being read in the Read() Method.
+//4. Handling of unique particle attribution of sequences is incomplete. Note that it is W3C specification that is so buggy. Basically there is neither formalization nor even normative definition about unique particle attribution. Appendix H tried to describe about that, but it is too incomplete.

+ 282 - 27
mcs/class/System.XML/System.Xml.Schema/BuiltInDatatype.cs

@@ -28,17 +28,58 @@ namespace Mono.Xml.Schema
 		Total
 	}
 
-	public abstract class XsdAnySimpleType : XmlSchemaDatatype
+	public class XsdAnySimpleType : XmlSchemaDatatype
 	{
+		static XsdAnySimpleType instance;
+		static XsdAnySimpleType ()
+		{
+			instance = new XsdAnySimpleType ();
+		}
+
+		public static XsdAnySimpleType Instance {
+			get { return instance; }
+		}
+
+		readonly char [] whitespaceArray = new char [] {' '};
+
 		// Fundamental Facets
-		public abstract bool Bounded { get; }
+		public virtual bool Bounded {
+			get { return false; }
+		}
 
-		public abstract bool Finite { get; }
+		public virtual bool Finite {
+			get { return false; }
+		}
 
-		public abstract bool Numeric { get; }
+		public virtual bool Numeric { 
+			get { return false; }
+		}
 
-		public abstract XsdOrderedFacet Ordered { get; }
+		public virtual XsdOrderedFacet Ordered { 
+			get { return XsdOrderedFacet.False; }
+		}
+
+		public override Type ValueType {
+			get { return typeof (object); }
+		}
+
+		public override XmlTokenizedType TokenizedType {
+			get {
+				return XmlTokenizedType.None;
+			}
+		}
+
+		public override object ParseValue (string s,
+			XmlNameTable nameTable, XmlNamespaceManager nsmgr)
+		{
+			return Normalize (s);
+		}
 
+		internal object ParseListValue (string s,
+			XmlNameTable nameTable, XmlNamespaceManager nsmgr)
+		{
+			return this.Normalize (s).Split (whitespaceArray);
+		}
 	}
 
 	// xs:string
@@ -56,12 +97,6 @@ namespace Mono.Xml.Schema
 			get { return typeof (string); }
 		}
 
-		public override object ParseValue (string s,
-			XmlNameTable nameTable, XmlNamespaceManager nsmgr)
-		{
-			return Normalize (s);
-		}
-
 		// Fundamental Facets
 		public override bool Bounded {
 			get { return false; }
@@ -159,7 +194,14 @@ namespace Mono.Xml.Schema
 			get { return typeof (string); }
 		}
 
-		// ParseValue () method is as same as that of xs:string
+		public override object ParseValue (string s,
+			XmlNameTable nameTable, XmlNamespaceManager nsmgr)
+		{
+			if (!XmlChar.IsNmToken (s))
+				throw new ArgumentException ("'" + s + "' is an invalid NMTOKEN.");
+			return s;
+		}
+
 	}
 
 	// xs:NMTOKENS
@@ -177,10 +219,9 @@ namespace Mono.Xml.Schema
 			get { return typeof (string []); }
 		}
 
-		readonly char [] whitespaceArray = new char [] {' '};
 		public override object ParseValue (string value, XmlNameTable nt, XmlNamespaceManager nsmgr)
 		{
-			return this.Normalize (value).Split (whitespaceArray);
+			return ParseListValue (value, nt, nsmgr);
 		}
 	}
 
@@ -199,7 +240,13 @@ namespace Mono.Xml.Schema
 			get { return typeof (string); }
 		}
 
-		// ParseValue () method is as same as that of xs:string
+		public override object ParseValue (string s,
+			XmlNameTable nameTable, XmlNamespaceManager nsmgr)
+		{
+			if (!XmlChar.IsName (s))
+				throw new ArgumentException ("'" + s + "' is an invalid name.");
+			return s;
+		}
 	}
 
 	// xs:NCName
@@ -217,7 +264,14 @@ namespace Mono.Xml.Schema
 			get { return typeof (string); }
 		}
 
-		// ParseValue () method is as same as that of xs:string
+		public override object ParseValue (string s,
+			XmlNameTable nameTable, XmlNamespaceManager nsmgr)
+		{
+			if (!XmlChar.IsNCName (s))
+				throw new ArgumentException ("'" + s + "' is an invalid NCName.");
+			return s;
+		}
+
 	}
 
 	// xs:ID
@@ -271,10 +325,9 @@ namespace Mono.Xml.Schema
 			get { return typeof (string []); }
 		}
 
-		readonly char [] whitespaceArray = new char [] {' '};
 		public override object ParseValue (string value, XmlNameTable nt, XmlNamespaceManager nsmgr)
 		{
-			return this.Normalize (value).Split (whitespaceArray);
+			return ParseListValue (value, nt, nsmgr);
 		}
 	}
 
@@ -313,10 +366,9 @@ namespace Mono.Xml.Schema
 			get { return typeof (string []); }
 		}
 
-		readonly char [] whitespaceArray = new char [] {' '};
 		public override object ParseValue (string value, XmlNameTable nt, XmlNamespaceManager nsmgr)
 		{
-			return this.Normalize (value).Split (whitespaceArray);
+			return ParseListValue (value, nt, nsmgr);
 		}
 	}
 
@@ -338,7 +390,7 @@ namespace Mono.Xml.Schema
 		public override object ParseValue (string s,
 			XmlNameTable nameTable, XmlNamespaceManager nsmgr)
 		{
-			throw new NotImplementedException ();
+			return Normalize (s);
 		}
 
 		// Fundamental Facets
@@ -374,7 +426,7 @@ namespace Mono.Xml.Schema
 		}
 
 		public override XmlTokenizedType TokenizedType {
-			get { return XmlTokenizedType.CDATA; }
+			get { return XmlTokenizedType.None; }
 		}
 
 		public override Type ValueType {
@@ -415,6 +467,11 @@ namespace Mono.Xml.Schema
 	// xs:integer
 	public class XsdInteger : XsdDecimal
 	{
+		public XsdInteger ()
+		{
+			this.WhitespaceValue = XsdWhitespaceFacet.Collapse;
+		}
+
 		// Here it may be bigger than int's (or long's) MaxValue.
 		public override Type ValueType {
 			get { return typeof (decimal); }
@@ -428,7 +485,7 @@ namespace Mono.Xml.Schema
 	}
 
 	// xs:Long
-	public class XsdLong : XsdNonNegativeInteger
+	public class XsdLong : XsdInteger
 	{
 		public override Type ValueType {
 			get { return typeof (long); }
@@ -608,8 +665,22 @@ namespace Mono.Xml.Schema
 	}
 
 	// xs:float
-	public class XsdFloat : XsdDecimal
+	public class XsdFloat : XsdAnySimpleType
 	{
+		// Fundamental Facets
+		public override bool Bounded {
+			get { return true; }
+		}
+		public override bool Finite {
+			get { return true; }
+		}
+		public override bool Numeric {
+			get { return true; }
+		}
+		public override XsdOrderedFacet Ordered {
+			get { return XsdOrderedFacet.Total; }
+		}
+
 		public override Type ValueType {
 			get { return typeof (float); }
 		}
@@ -622,8 +693,22 @@ namespace Mono.Xml.Schema
 	}
 
 	// xs:double
-	public class XsdDouble : XsdDecimal
+	public class XsdDouble : XsdAnySimpleType
 	{
+		// Fundamental Facets
+		public override bool Bounded {
+			get { return true; }
+		}
+		public override bool Finite {
+			get { return true; }
+		}
+		public override bool Numeric {
+			get { return true; }
+		}
+		public override XsdOrderedFacet Ordered {
+			get { return XsdOrderedFacet.Total; }
+		}
+
 		public override Type ValueType {
 			get { return typeof (double); }
 		}
@@ -653,6 +738,64 @@ namespace Mono.Xml.Schema
 		}
 	}
 
+	// xs:hexBinary
+	public class XsdHexBinary : XsdAnySimpleType
+	{
+		internal XsdHexBinary ()
+		{
+		}
+
+		public override XmlTokenizedType TokenizedType {
+			get { return XmlTokenizedType.None; }
+		}
+
+		public override Type ValueType {
+			get { return typeof (byte []); }
+		}
+
+		[MonoTODO]
+		public override object ParseValue (string s,
+			XmlNameTable nameTable, XmlNamespaceManager nsmgr)
+		{
+			throw new NotImplementedException ();
+		}
+
+		// Fundamental Facets ... no need to override
+	}
+
+	// xs:QName
+	public class XsdQName : XsdName
+	{
+		internal XsdQName ()
+		{
+		}
+
+		// Fundamental facets are the same as anySimpleType.
+
+		public override XmlTokenizedType TokenizedType {
+			get { return XmlTokenizedType.QName; }
+		}
+
+		public override Type ValueType {
+			get { return typeof (XmlQualifiedName); }
+		}
+
+		// ParseValue () method is as same as that of xs:string
+		public override object ParseValue (string s,
+			XmlNameTable nameTable, XmlNamespaceManager nsmgr)
+		{
+			if (nameTable == null)
+				throw new ArgumentNullException ("name table");
+			if (nsmgr == null)
+				throw new ArgumentNullException ("namespace manager");
+			int colonAt = s.IndexOf (':');
+			string localName = 
+				nameTable.Add (colonAt < 0 ? s : s.Substring (colonAt + 1));
+			return new XmlQualifiedName (localName, nsmgr.LookupNamespace (
+				colonAt < 0 ? "" : s.Substring (0, colonAt - 1)));
+		}
+	}
+
 	// xs:boolean
 	public class XsdBoolean : XsdAnySimpleType
 	{
@@ -708,6 +851,42 @@ namespace Mono.Xml.Schema
 		}
 	}
 	
+	// xs:duration
+	public class XsdDuration : XsdAnySimpleType
+	{
+		internal XsdDuration ()
+		{
+		}
+
+		public override XmlTokenizedType TokenizedType {
+			get { return XmlTokenizedType.CDATA; }
+		}
+
+		public override Type ValueType {
+			get { return typeof (TimeSpan); }
+		}
+
+		public override object ParseValue (string s,
+			XmlNameTable nameTable, XmlNamespaceManager nsmgr)
+		{
+			return XmlConvert.ToTimeSpan (s);
+		}
+
+		// Fundamental Facets
+		public override bool Bounded {
+			get { return false; }
+		}
+		public override bool Finite {
+			get { return false; }
+		}
+		public override bool Numeric {
+			get { return false; }
+		}
+		public override XsdOrderedFacet Ordered {
+			get { return XsdOrderedFacet.Partial; }
+		}
+	}
+
 	// xs:dateTime
 	public class XsdDateTime : XsdAnySimpleType
 	{
@@ -734,13 +913,13 @@ namespace Mono.Xml.Schema
 			get { return false; }
 		}
 		public override bool Finite {
-			get { return true; }
+			get { return false; }
 		}
 		public override bool Numeric {
 			get { return false; }
 		}
 		public override XsdOrderedFacet Ordered {
-			get { return XsdOrderedFacet.Total; }
+			get { return XsdOrderedFacet.Partial; }
 		}
 	}
 
@@ -763,4 +942,80 @@ namespace Mono.Xml.Schema
 			return DateTime.ParseExact (s, "HH:mm:ss.fffffffzzz", null);
 		}
 	}
+
+	// xs:gYearMonth
+	public class XsdGYearMonth : XsdAnySimpleType
+	{
+		public override Type ValueType {
+			get { return typeof (DateTime); }
+		}
+
+		[MonoTODO]
+		public override object ParseValue (string s,
+			XmlNameTable nameTable, XmlNamespaceManager nsmgr)
+		{
+			return XmlConvert.ToDateTime (Normalize (s));
+		}
+	}
+
+	// xs:gMonthDay
+	public class XsdGMonthDay : XsdAnySimpleType
+	{
+		public override Type ValueType {
+			get { return typeof (DateTime); }
+		}
+
+		[MonoTODO]
+		public override object ParseValue (string s,
+			XmlNameTable nameTable, XmlNamespaceManager nsmgr)
+		{
+			return XmlConvert.ToDateTime (Normalize (s));
+		}
+	}
+
+	// xs:gYear
+	public class XsdGYear : XsdAnySimpleType
+	{
+		public override Type ValueType {
+			get { return typeof (DateTime); }
+		}
+
+		[MonoTODO]
+		public override object ParseValue (string s,
+			XmlNameTable nameTable, XmlNamespaceManager nsmgr)
+		{
+			return new DateTime (int.Parse (s), 1, 1);
+		}
+	}
+
+	// xs:gMonth
+	public class XsdGMonth : XsdAnySimpleType
+	{
+		public override Type ValueType {
+			get { return typeof (DateTime); }
+		}
+
+		[MonoTODO]
+		public override object ParseValue (string s,
+			XmlNameTable nameTable, XmlNamespaceManager nsmgr)
+		{
+			return new DateTime (0, int.Parse (s), 1);
+		}
+	}
+
+	// xs:gDay
+	public class XsdGDay : XsdAnySimpleType
+	{
+		public override Type ValueType {
+			get { return typeof (DateTime); }
+		}
+
+		[MonoTODO]
+		public override object ParseValue (string s,
+			XmlNameTable nameTable, XmlNamespaceManager nsmgr)
+		{
+			return new DateTime (0, 1, int.Parse (s));
+		}
+	}
+
 }

+ 36 - 0
mcs/class/System.XML/System.Xml.Schema/ChangeLog

@@ -1,3 +1,33 @@
+2003-09-30  Atsushi Enomoto  <[email protected]>
+
+	* Forgot to append 8/24/2003 ChangeLog.
+	* BUGS.txt, BUGS-MS.txt : Appended additional bug info.
+	* BuiltInDatatype.cs, ValidationHandler.cs, XmlSchema.cs, 
+	  XmlSchemaAll.cs, XmlSchemaAnnotation.cs. XmlSchemaAny.cs,
+	  XmlSchemaAnyAttribute.cs, XmlSchemaAttribute.cs,
+	  XmlSchemaAttributeGroup.cs, XmlSchemaAttributeGroupRef.cs,
+	  XmlSchemaChoice.cs, XmlSchemaCollection.cs,
+	  XmlSchemaComplexContent.cs, XmlSchemaComplexContentExtension.cs,
+	  XmlSchemaComplexContentRestriction.cs, XmlSchemaComplexType.cs,
+	  XmlSchemaContent.cs, XmlSchemaDatatype.cs, XmlSchemaElement.cs,
+	  XmlSchemaException.cs, XmlSchemaGroup.cs, XmlSchemaGroupBase.cs,
+	  XmlSchemaGroupRef.cs, XmlSchemaIdentityConstraint.cs,
+	  XmlSchemaKey.cs, XmlSchemaKeyref.cs, XmlSchemaNotation.cs,
+	  XmlSchemaObject.cs, XmlSchemaObjectTable.cs, XmlSchemaParticle.cs,
+	  XmlSchemaReader.cs, XmlSchemaSequence.cs, XmlSchemaSimpleContent.cs,
+	  XmlSchemaSimpleContentExtension.cs,
+	  XmlSchemaSimpleContentRestriction.cs, XmlSchemaSimpleType.cs,
+	  XmlSchemaSimpleTypeContent.cs, XmlSchemaSimpleTypeList.cs,
+	  XmlSchemaSimpleTypeRestriction.cs, XmlSchemaSimpleTypeUnion.cs,
+	  XmlSchemaType.cs, XmlSchemaUnique.cs, XmlSchemaUtil.cs,
+	  XmlSchemaXPath.cs :
+
+	  - Almost all classes are changed to implement schema component
+	    constraints, and schema validation using XsdValidatingReader.
+	  - better exception messages.
+	  - More datatype support.
+	  and so on.
+
 2003-09-14  Lluis Sanchez Gual <[email protected]>
 
 	* XmlSchema.cs: Do not add schema namespace declaration if it is already
@@ -7,6 +37,12 @@
 
 	* BuiltInDatatypes.cs, XmlSchemaDatatype.cs: Added double type.
 
+2003-08-24  Atsushi Enomoto  <[email protected]>
+
+	* BuiltInDatatype.cs : XsdDecimal.TokenizedType should be None.
+	* XmlSchemaCollection.cs : Add(uri) should not reject chameleon schema.
+	  Add() should compile specified schema.
+
 2003-08-08  Lluis Sanchez Gual <[email protected]>
 
 	* BuiltInDatatypes.cs, XmlSchemaDatatype.cs: Added XsdAnyURI,

+ 17 - 2
mcs/class/System.XML/System.Xml.Schema/ValidationHandler.cs

@@ -12,9 +12,16 @@ namespace System.Xml.Schema
 	/// </summary>
 	internal class ValidationHandler
 	{
-		public static void RaiseValidationEvent(ValidationEventHandler handle, Exception innerException,  object sender, string message, XmlSeverityType severity)
+		public static void RaiseValidationEvent(ValidationEventHandler handle,
+			Exception innerException,
+			string message,
+			XmlSchemaObject xsobj,
+			object sender,
+			string sourceUri,
+			XmlSeverityType severity)
 		{
-			XmlSchemaException ex = new XmlSchemaException(message,innerException);
+			XmlSchemaException ex = new XmlSchemaException (
+				message, sender, sourceUri, xsobj, innerException);
 			ValidationEventArgs e = new ValidationEventArgs(ex,message,severity);
 			if(handle == null)
 			{
@@ -25,6 +32,13 @@ namespace System.Xml.Schema
 				handle(sender,e);
 			}
 		}
+
+		/*
+		public static void RaiseValidationEvent(ValidationEventHandler handle, Exception innerException,  object sender, string message, XmlSeverityType severity)
+		{
+			RaiseValidationEvent(handle,null,sender,message,XmlSeverityType.Error);
+		}
+
 		public static void RaiseValidationError(ValidationEventHandler handle, object sender, string message)
 		{
 			RaiseValidationEvent(handle,null,sender,message,XmlSeverityType.Error);
@@ -44,5 +58,6 @@ namespace System.Xml.Schema
 		{
 			RaiseValidationEvent(handle, innerException, null, message, XmlSeverityType.Warning);
 		}
+		*/
 	}
 }

+ 148 - 182
mcs/class/System.XML/System.Xml.Schema/XmlSchema.cs

@@ -43,12 +43,16 @@ namespace System.Xml.Schema
                 private string version;
                 private string language;
 
-		// post schema compilation infoset
+		// other post schema compilation infoset
 		private Hashtable idCollection;
-		private Hashtable missingBaseSchemaTypeRefs;
-		private ArrayList missingElementTypeRefs;
+		private XmlSchemaObjectTable namedIdentities;
 		private XmlSchemaCollection schemas;
 
+		private XmlNameTable nameTable;
+		private XmlResolver resolver;
+
+		internal bool missedSubComponents;
+
                 // Compiler specific things
                 private static string xmlname = "schema";
 
@@ -68,8 +72,7 @@ namespace System.Xml.Schema
                         notations                       = new XmlSchemaObjectTable();
                         schemaTypes                     = new XmlSchemaObjectTable();
 			idCollection                    = new Hashtable ();
-			missingBaseSchemaTypeRefs       = new Hashtable ();
-			missingElementTypeRefs          = new ArrayList ();
+                        namedIdentities                 = new XmlSchemaObjectTable();
                 }
 
                 #region Properties
@@ -224,14 +227,9 @@ namespace System.Xml.Schema
 			get { return idCollection; }
 		}
 
-		internal Hashtable MissingBaseSchemaTypeRefs
-		{
-			get { return missingBaseSchemaTypeRefs; }
-		}
-
-		internal ArrayList MissingElementTypeRefs
+		internal XmlSchemaObjectTable NamedIdentities
 		{
-			get { return missingElementTypeRefs; }
+			get { return namedIdentities; }
 		}
 
 		internal XmlSchemaCollection Schemas
@@ -260,22 +258,36 @@ namespace System.Xml.Schema
                 [MonoTODO]
                 public void Compile(ValidationEventHandler handler)
 		{
-			Compile (handler, new Stack (), this);
+			Compile (handler, new Stack (), this, null);
 			isCompiled = true;
 		}
 
-		private void Compile (ValidationEventHandler handler, Stack schemaLocationStack, XmlSchema rootSchema)
+		internal void Compile (ValidationEventHandler handler, XmlSchemaCollection col)
+		{
+			Compile (handler, new Stack (), this, col);
+		}
+
+		private void Compile (ValidationEventHandler handler, Stack schemaLocationStack, XmlSchema rootSchema, XmlSchemaCollection col)
                 {
-			CompilationId = Guid.NewGuid ();
-			schemas = new XmlSchemaCollection ();
+			if (rootSchema != this) {
+				CompilationId = rootSchema.CompilationId;
+				schemas = rootSchema.schemas;
+			}
+			else {
+				schemas = col;
+				if (schemas == null) {
+					schemas = new XmlSchemaCollection ();
+					schemas.CompilationId = Guid.NewGuid ();
+				}
+				CompilationId = schemas.CompilationId;
+				this.idCollection.Clear ();
+			}
 			schemas.Add (this);
 
 			attributeGroups = new XmlSchemaObjectTable ();
 			attributes = new XmlSchemaObjectTable ();
 			elements = new XmlSchemaObjectTable ();
 			groups = new XmlSchemaObjectTable ();
-			missingElementTypeRefs.Clear ();
-			missingBaseSchemaTypeRefs.Clear ();
 			notations = new XmlSchemaObjectTable ();
 			schemaTypes = new XmlSchemaObjectTable ();
 
@@ -319,106 +331,101 @@ namespace System.Xml.Schema
 			foreach (XmlSchemaObject obj in Items)
 				compilationItems.Add (obj);
 
+			// First, we run into inclusion schemas to collect 
+			// compilation target items into compiledItems.
                         foreach(XmlSchemaObject obj in Includes)
                         {
 				XmlSchemaExternal ext = obj as XmlSchemaExternal;
                                 if(ext != null)
                                 {
-					if (ext.SchemaLocation == null) continue;
+					if (ext.SchemaLocation == null) 
+						continue;
 					string url = GetResolvedUri (ext.SchemaLocation);
-					XmlSchemaInclude include = ext as XmlSchemaInclude;
-					if (include != null) {
-						if (schemaLocationStack.Contains (url)) {
-							error(handler, "Nested inclusion was found: " + url);
-							// must skip this inclusion
-							continue;
-						}
-						schemaLocationStack.Push (url);
-						XmlSchema includedSchema = XmlSchema.Read (new XmlTextReader (url), handler);
-						includedSchema.schemas = schemas;
-						includedSchema.Compile (handler, schemaLocationStack, rootSchema);
-						schemaLocationStack.Pop ();
-						foreach (XmlSchemaObject includedObj in includedSchema.Items)
-							compilationItems.Add (includedObj);
+					Stream stream = null;
+					if (schemaLocationStack.Contains (url)) {
+						error(handler, "Nested inclusion was found: " + url);
+						// must skip this inclusion
+						continue;
 					}
+					try {
+						if (resolver == null)
+							resolver = new XmlUrlResolver ();
+						stream = resolver.GetEntity (new Uri (url), null, typeof (Stream)) as Stream;
+					} catch (Exception ex) {
+						// FIXME: This is not good way to handle errors.
+						stream = null;
+					}
+
+					// Process redefinition children in advance.
 					XmlSchemaRedefine redefine = obj as XmlSchemaRedefine;
 					if (redefine != null) {
+						foreach (XmlSchemaObject redefinedObj in redefine.Items) {
+							redefinedObj.isRedefinedComponent = true;
+							redefinedObj.isRedefineChild = true;
+							if (redefinedObj is XmlSchemaType ||
+								redefinedObj is XmlSchemaGroup ||
+								redefinedObj is XmlSchemaAttributeGroup)
+								compilationItems.Add (redefinedObj);
+							else
+								error (handler, "Redefinition is only allowed to simpleType, complexType, group and attributeGroup.");
+						}
+					}
 
-	                                        //FIXME: Kuch to karo! (Do Something ;)
-						throw new NotImplementedException ();
+					XmlSchema includedSchema = null;
+					if (stream == null) {
+						// It is missing schema components.
+						missedSubComponents = true;
+						continue;
+					} else {
+						schemaLocationStack.Push (url);
+						includedSchema = XmlSchema.Read (new XmlTextReader (url, stream, nameTable), handler);
+						includedSchema.schemas = schemas;
+					}
 
-						if (schemaLocationStack.Contains (url)) {
-							error(handler, "Nested inclusion was found: " + url);
-							// must skip this inclusion
+					// Set - actual - target namespace for the included schema * before compilation*.
+					XmlSchemaImport import = ext as XmlSchemaImport;
+					if (import != null) {
+						if (TargetNamespace == includedSchema.TargetNamespace) {
+							error (handler, "Target namespace must be different from that of included schema.");
+							continue;
+						} else if (includedSchema.TargetNamespace != import.Namespace) {
+							error (handler, "Attribute namespace and its importing schema's target namespace must be the same.");
 							continue;
 						}
-					}
-					XmlSchemaImport import = obj as XmlSchemaImport;
-					if (import != null) {
-						if (schemaLocationStack.Contains (url)) {
-							error(handler, "Nested inclusion was found: " + url);
-							// must skip this inclusion
+					} else {
+						if (TargetNamespace == null && 
+							includedSchema.TargetNamespace != null) {
+							error (handler, "Target namespace is required to include a schema which has its own target namespace");
 							continue;
 						}
-						schemaLocationStack.Push (url);
-						XmlSchema includedSchema = XmlSchema.Read (new XmlTextReader (url), handler);
-						includedSchema.schemas = schemas;
-						includedSchema.Compile (handler, schemaLocationStack, rootSchema);
-						schemaLocationStack.Pop ();
-						// TODO: check targetNamespace constraints
-						rootSchema.schemas.Add (includedSchema);
-						foreach (XmlSchemaElement element in includedSchema.Elements)
-							elements.Add (element.QualifiedName, element);
-						foreach (XmlSchemaAttribute attribute in includedSchema.Attributes)
-							attributes.Add (attribute.QualifiedName, attribute);
-						foreach (XmlSchemaAttributeGroup attrGroup in includedSchema.AttributeGroups)
-							attributeGroups.Add (attrGroup.QualifiedName, attrGroup);
-						foreach (XmlSchemaGroup group in includedSchema.Groups)
-							groups.Add (group.QualifiedName, group);
-						foreach (XmlSchemaGroup group in includedSchema.Groups)
-							groups.Add (group.QualifiedName, group);
-						foreach (XmlSchemaNotation notation in includedSchema.Notations)
-							notations.Add (notation.QualifiedName, notation);
-						foreach (XmlSchemaType schemaType in includedSchema.SchemaTypes)
-							schemaTypes.Add (schemaType.QualifiedName, schemaType);
+						else if (TargetNamespace != null && 
+							includedSchema.TargetNamespace == null)
+							includedSchema.TargetNamespace = TargetNamespace;
 					}
+
+					// Compile included schema.
+					includedSchema.idCollection = this.IDCollection;
+					includedSchema.Compile (handler, schemaLocationStack, rootSchema, col);
+					schemaLocationStack.Pop ();
+
+					if (import != null)
+						rootSchema.schemas.Add (includedSchema);
+
+					// Add compiled items.
+					foreach (XmlSchemaObject includedObj in includedSchema.Items)
+						compilationItems.Add (includedObj);
                                 }
                                 else
                                 {
                                         error(handler,"Object of Type "+obj.GetType().Name+" is not valid in Includes Property of XmlSchema");
                                 }
                         }
-			// It is hack, but types are required before element/attributes.
-			foreach (XmlSchemaObject obj in compilationItems)
-			{
-                                if(obj is XmlSchemaComplexType)
-                                {
-                                        XmlSchemaComplexType ctype = (XmlSchemaComplexType) obj;
-                                        ctype.istoplevel = true;
-                                        int numerr = ctype.Compile(handler, this);
-                                        errorCount += numerr;
-                                        if(numerr == 0)
-                                        {
-                                                schemaTypes.Add(ctype.QualifiedName, ctype);
-                                        }
-                                }
-                                else if(obj is XmlSchemaSimpleType)
-                                {
-                                        XmlSchemaSimpleType stype = (XmlSchemaSimpleType) obj;
-                                        stype.islocal = false; //This simple type is toplevel
-                                        int numerr = stype.Compile(handler, this);
-                                        errorCount += numerr;
-                                        if(numerr == 0)
-                                        {
-                                                SchemaTypes.Add(stype.QualifiedName, stype);
-                                        }
-                                }
-			}
-			// Add missing references.
-			foreach (XmlSchemaComplexType cType in missingBaseSchemaTypeRefs.Keys)
-				cType.BaseSchemaTypeInternal = 
-					SchemaTypes [missingBaseSchemaTypeRefs [cType] as XmlQualifiedName];
 
+			// Compilation phase.
+			// At least each Compile() must gives unique (qualified) name for each component.
+			// It also checks self-resolvable properties correct.
+			// Post compilation schema information contribution is not required here.
+			// It should be done by Validate().
 			foreach(XmlSchemaObject obj in compilationItems)
                         {
                                 if(obj is XmlSchemaAnnotation)
@@ -433,12 +440,12 @@ namespace System.Xml.Schema
                                 else if(obj is XmlSchemaAttribute)
                                 {
                                         XmlSchemaAttribute attr = (XmlSchemaAttribute) obj;
-                                        attr.parentIsSchema = true;
+                                        attr.ParentIsSchema = true;
                                         int numerr = attr.Compile(handler, this);
                                         errorCount += numerr;
                                         if(numerr == 0)
                                         {
-                                                Attributes.Set(attr.QualifiedName, attr);
+                                                XmlSchemaUtil.AddToTable (Attributes, attr, attr.QualifiedName, handler);
                                         }
                                 }
                                 else if(obj is XmlSchemaAttributeGroup)
@@ -448,16 +455,30 @@ namespace System.Xml.Schema
                                         errorCount += numerr;
                                         if(numerr == 0)
                                         {
-                                                AttributeGroups.Set(attrgrp.QualifiedName, attrgrp);
+                                                XmlSchemaUtil.AddToTable (AttributeGroups, attrgrp, attrgrp.QualifiedName, handler);
                                         }
                                 }
                                 else if(obj is XmlSchemaComplexType)
                                 {
-					// Do nothing here.
+                                        XmlSchemaComplexType ctype = (XmlSchemaComplexType) obj;
+                                        ctype.ParentIsSchema = true;
+                                        int numerr = ctype.Compile(handler, this);
+                                        errorCount += numerr;
+                                        if(numerr == 0)
+                                        {
+                                                XmlSchemaUtil.AddToTable (schemaTypes, ctype, ctype.QualifiedName, handler);
+                                        }
                                 }
                                 else if(obj is XmlSchemaSimpleType)
                                 {
-					// Do nothing here.
+                                        XmlSchemaSimpleType stype = (XmlSchemaSimpleType) obj;
+                                        stype.islocal = false; //This simple type is toplevel
+                                        int numerr = stype.Compile(handler, this);
+                                        errorCount += numerr;
+                                        if(numerr == 0)
+                                        {
+                                                XmlSchemaUtil.AddToTable (SchemaTypes, stype, stype.QualifiedName, handler);
+                                        }
                                 }
                                 else if(obj is XmlSchemaElement)
                                 {
@@ -467,7 +488,7 @@ namespace System.Xml.Schema
                                         errorCount += numerr;
                                         if(numerr == 0)
                                         {
-                                                Elements.Set(elem.QualifiedName,elem);
+                                                XmlSchemaUtil.AddToTable (Elements, elem, elem.QualifiedName, handler);
                                         }
                                 }
                                 else if(obj is XmlSchemaGroup)
@@ -477,7 +498,7 @@ namespace System.Xml.Schema
                                         errorCount += numerr;
                                         if(numerr == 0)
                                         {
-                                                Groups.Set(grp.QualifiedName,grp);
+                                                XmlSchemaUtil.AddToTable (Groups, grp, grp.QualifiedName, handler);
                                         }
                                 }
                                 else if(obj is XmlSchemaNotation)
@@ -487,42 +508,21 @@ namespace System.Xml.Schema
                                         errorCount += numerr;
                                         if(numerr == 0)
                                         {
-                                                Notations.Set(ntn.QualifiedName, ntn);
+                                                XmlSchemaUtil.AddToTable (Notations, ntn, ntn.QualifiedName, handler);
                                         }
                                 }
                                 else
                                 {
-                                        ValidationHandler.RaiseValidationError(handler,this,
-                                                "Object of Type "+obj.GetType().Name+" is not valid in Item Property of Schema");
+                                        ValidationHandler.RaiseValidationEvent (
+						handler, null,
+                                                "Object of Type "+obj.GetType().Name+" is not valid in Item Property of Schema",
+						null, this, null, XmlSeverityType.Error);
                                 }
                         }
 
 			if (rootSchema == this)
-			{
-				// First, fill type information for type reference
-				foreach (XmlSchemaElement element in missingElementTypeRefs)
-				{
-					if (element.SchemaTypeName != XmlQualifiedName.Empty)
-					{
-						XmlSchemaType type = FindSchemaType (element.SchemaTypeName);
-						// If el is null, then it is missing sub components ... ?
-						element.SetSchemaType (type);
-					}
-				}
-				// Then, fill type information for the type references for the referencing elements
-				foreach (XmlSchemaElement element in missingElementTypeRefs)
-				{
-					if (element.RefName != XmlQualifiedName.Empty)
-					{
-						XmlSchemaElement refElem = FindElement (element.RefName);
-						// If el is null, then it is missing sub components ... ?
-						if (refElem != null) element.SetSchemaType (refElem.ElementType);
-					}
-				}
-			}
-
-			Validate(handler);
-                }
+				Validate(handler);
+		}
 
 		private string GetResolvedUri (string relativeUri)
 		{
@@ -537,71 +537,34 @@ namespace System.Xml.Schema
                 [MonoTODO]
                 private void Validate(ValidationEventHandler handler)
                 {
+			ValidationId = CompilationId;
+
                         foreach(XmlSchemaAttribute attr in Attributes.Values)
                         {
-                                attr.Validate(handler, this);
+                                errorCount += attr.Validate(handler, this);
                         }
                         foreach(XmlSchemaAttributeGroup attrgrp in AttributeGroups.Values)
                         {
-                                attrgrp.Validate(handler);
+                                errorCount += attrgrp.Validate(handler, this);
                         }
                         foreach(XmlSchemaType type in SchemaTypes.Values)
                         {
-                                if(type is XmlSchemaComplexType)
-                                {
-                                        ((XmlSchemaComplexType)type).Validate(handler);
-                                }
-                                else
-                                        ((XmlSchemaSimpleType)type).Validate(handler, this);
+                                errorCount += type.Validate(handler, this);
                         }
                         foreach(XmlSchemaElement elem in Elements.Values)
                         {
-                                elem.Validate(handler);
+                                errorCount += elem.Validate(handler, this);
                         }
                         foreach(XmlSchemaGroup grp in Groups.Values)
                         {
-                                grp.Validate(handler);
+                                errorCount += grp.Validate(handler, this);
                         }
                         foreach(XmlSchemaNotation ntn in Notations.Values)
                         {
-                                ntn.Validate(handler);
+                                errorCount += ntn.Validate(handler, this);
                         }
                 }
 
-		internal XmlSchemaElement FindElement (XmlQualifiedName name)
-		{
-			if (name.Namespace != TargetNamespace)
-				return null;
-
-			XmlSchema target = schemas [name.Namespace];
-			if (target == null)
-				return null;
-
-			foreach (XmlSchemaObject obj in target.Items) {
-				XmlSchemaElement elem = obj as XmlSchemaElement;
-				if (elem != null && elem.Name == name.Name)
-					return elem;
-			}
-			return null;
-		}
-
-		internal XmlSchemaType FindSchemaType (XmlQualifiedName name)
-		{
-			if (name.Namespace != TargetNamespace)
-				return null;
-
-			XmlSchema target = schemas [name.Namespace];
-			if (target == null)
-				return null;
-
-			foreach (XmlSchemaObject obj in target.Items) {
-				XmlSchemaType type = obj as XmlSchemaType;
-				if (type != null && type.Name == name.Name)
-					return type;
-			}
-			return null;
-		}
-
                 #region Read
 
                 public static XmlSchema Read(TextReader reader, ValidationEventHandler validationEventHandler)
@@ -616,13 +579,15 @@ namespace System.Xml.Schema
 		[MonoTODO ("Use ValidationEventHandler")]
                 public static XmlSchema Read(XmlReader rdr, ValidationEventHandler validationEventHandler)
                 {
+/*
 			string baseURI = rdr.BaseURI;
                         XmlSerializer xser = new XmlSerializer (typeof (XmlSchema));
                         XmlSchema schema = (XmlSchema) xser.Deserialize (rdr);
 			schema.SourceUri = baseURI;
 			schema.Compile (validationEventHandler);
+			schema.nameTable = rdr.NameTable;
 			return schema;
-/*
+*/
 			XmlSchemaReader reader = new XmlSchemaReader(rdr, validationEventHandler);
 
                         while(reader.ReadNextElement())
@@ -633,6 +598,7 @@ namespace System.Xml.Schema
                                                 if(reader.LocalName == "schema")
                                                 {
                                                         XmlSchema schema = new XmlSchema();
+							schema.nameTable = rdr.NameTable;
 
                                                         schema.LineNumber = reader.LineNumber;
                                                         schema.LinePosition = reader.LinePosition;
@@ -659,10 +625,9 @@ namespace System.Xml.Schema
                                 }
                         }
                         throw new XmlSchemaException("The top level schema must have namespace "+XmlSchema.Namespace, null);
-*/
                 }
-/*
-                private static void ReadAttributes(XmlSchema schema, XmlSchemaReader reader, ValidationEventHandler h)
+
+		private static void ReadAttributes(XmlSchema schema, XmlSchemaReader reader, ValidationEventHandler h)
                 {
                         Exception ex;
 
@@ -677,7 +642,8 @@ namespace System.Xml.Schema
                                                         error(h, reader.Value + " is not a valid value for attributeFormDefault.", ex);
                                                 break;
                                         case "blockDefault" :
-                                                schema.blockDefault = XmlSchemaUtil.ReadDerivationAttribute(reader,out ex, "blockDefault");
+                                                schema.blockDefault = XmlSchemaUtil.ReadDerivationAttribute(reader,out ex, "blockDefault",
+							XmlSchemaUtil.ElementBlockAllowed);
                                                 if(ex != null)
                                                         warn(h, ex.Message, ex);
                                                 break;
@@ -687,7 +653,8 @@ namespace System.Xml.Schema
                                                         error(h, reader.Value + " is not a valid value for elementFormDefault.", ex);
                                                 break;
                                         case "finalDefault":
-                                                schema.finalDefault = XmlSchemaUtil.ReadDerivationAttribute(reader, out ex, "finalDefault");
+                                                schema.finalDefault = XmlSchemaUtil.ReadDerivationAttribute(reader, out ex, "finalDefault",
+							XmlSchemaUtil.FinalAllowed);
                                                 if(ex != null)
                                                         warn(h, ex.Message , ex);
                                                 break;
@@ -826,7 +793,6 @@ namespace System.Xml.Schema
                                 reader.RaiseInvalidElementError();
                         }
                 }
-*/
 		#endregion
 
                 #region write

+ 103 - 6
mcs/class/System.XML/System.Xml.Schema/XmlSchemaAll.cs

@@ -1,6 +1,12 @@
-// Author: Dwivedi, Ajay kumar
-//            [email protected]
+//
+// System.Xml.Schema.XmlSchemaAll.cs
+//
+// Author:
+//	Dwivedi, Ajay kumar  [email protected]
+//	Atsushi Enomoto  [email protected]
+//
 using System;
+using System.Collections;
 using System.Xml;
 using System.Xml.Serialization;
 
@@ -12,7 +18,9 @@ namespace System.Xml.Schema
 	public class XmlSchemaAll : XmlSchemaGroupBase
 	{
 		private XmlSchemaObjectCollection items;
+		private XmlSchemaObjectCollection compiledItems;
 		private static string xmlname = "all";
+		private bool emptiable;
 
 		public XmlSchemaAll()
 		{
@@ -24,13 +32,21 @@ namespace System.Xml.Schema
 		{
 			get{ return items; }
 		}
+		internal XmlSchemaObjectCollection CompiledItems 
+		{
+			get{ return compiledItems; }
+		}
+		internal bool Emptiable
+		{
+			get { return emptiable; }
+		}
 
 		/// <remarks>
 		/// 1. MaxOccurs must be one. (default is also one)
 		/// 2. MinOccurs must be zero or one.
 		/// </remarks>
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
@@ -43,12 +59,13 @@ namespace System.Xml.Schema
 				error(h,"minOccurs must be 0 or 1");
 
 			XmlSchemaUtil.CompileID(Id, this, schema.IDCollection, h);
+			CompileOccurence (h, schema);
 
 			foreach(XmlSchemaObject obj in Items)
 			{
-				if(obj is XmlSchemaElement)
+				XmlSchemaElement elem = obj as XmlSchemaElement;
+				if(elem != null)
 				{
-					XmlSchemaElement elem = (XmlSchemaElement)obj;
 					if(elem.MaxOccurs != Decimal.One && elem.MaxOccurs != Decimal.Zero)
 					{
 						elem.error(h,"The {max occurs} of all the elements of 'all' must be 0 or 1. ");
@@ -66,10 +83,90 @@ namespace System.Xml.Schema
 		}
 
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
+			if (IsValidated (schema.CompilationId))
+				return errorCount;
+			this.CompileOccurence (h, schema);
+			// 3.8.6 All Group Limited :: 1.
+			// Beware that this section was corrected: E1-26 of http://www.w3.org/2001/05/xmlschema-errata#Errata1
+			if (!this.parentIsGroupDefinition && ValidatedMaxOccurs != 1)
+				error (h, "-all- group is limited to be content of a model group, or that of a complex type with maxOccurs to be 1.");
+
+			emptiable = true;
+			compiledItems = new XmlSchemaObjectCollection ();
+			foreach (XmlSchemaElement obj in Items) {
+				errorCount += obj.Validate (h, schema);
+				if (obj.ValidatedMaxOccurs != 0 &&
+					obj.ValidatedMaxOccurs != 1)
+					error (h, "MaxOccurs of a particle inside -all- compositor must be either 0 or 1.");
+				compiledItems.Add (obj);
+				if (obj.MinOccurs > 0)
+					emptiable = false;
+			}
+
+			ValidationId = schema.ValidationId;
 			return errorCount;
 		}
+
+		internal override void ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			XmlSchemaAny any = baseParticle as XmlSchemaAny;
+			XmlSchemaAll derivedAll = baseParticle as XmlSchemaAll;
+			if (any != null) {
+				// NSRecurseCheckCardinality
+				this.ValidateNSRecurseCheckCardinality (any, h, schema);
+				return;
+			} else if (derivedAll != null) {
+				// Recurse
+				ValidateOccurenceRangeOK (derivedAll, h, schema);
+
+				// FIXME: What is the correct "order preserving" mapping?
+				int baseIndex = 0;
+				for (int i = 0; i < this.Items.Count; i++) {
+					XmlSchemaParticle pd = Items [i] as XmlSchemaParticle;
+					if (derivedAll.Items.Count > baseIndex) {
+						XmlSchemaParticle pb = derivedAll.Items [baseIndex] as XmlSchemaParticle;
+						pd.ActualParticle.ValidateDerivationByRestriction (pb.ActualParticle, h, schema);
+						baseIndex++;
+					}
+					else
+						error (h, "Invalid choice derivation by extension was found.");
+				}
+
+				return;
+			}
+			else
+				error (h, "Invalid -all- particle derivation was found.");
+		}
+
+		internal override decimal GetMinEffectiveTotalRange ()
+		{
+			return GetMinEffectiveTotalRangeAllAndSequence ();
+		}
+
+		internal override void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema)
+		{
+			foreach (XmlSchemaElement el in this.Items)
+				el.CheckRecursion (depth, h, schema);
+		}
+
+		internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames, ArrayList nsNames,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			foreach (XmlSchemaElement el in this.Items)
+				el.ValidateUniqueParticleAttribution (qnames, nsNames, h, schema);
+		}
+
+		internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			foreach (XmlSchemaElement el in this.Items)
+				el.ValidateUniqueTypeAttribution (labels, h, schema);
+		}
+
+
 		//<all
 		//  id = ID
 		//  maxOccurs = 1 : 1

+ 2 - 2
mcs/class/System.XML/System.Xml.Schema/XmlSchemaAnnotation.cs

@@ -56,7 +56,7 @@ namespace System.Xml.Schema
 		}
 
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
@@ -67,7 +67,7 @@ namespace System.Xml.Schema
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
 			return 0;
 		}

+ 114 - 34
mcs/class/System.XML/System.Xml.Schema/XmlSchemaAny.cs

@@ -1,9 +1,12 @@
 // Author: Dwivedi, Ajay kumar
 //            [email protected]
 using System;
+using System.Collections;
+using System.Collections.Specialized;
 using System.Xml;
 using System.Xml.Serialization;
 using System.ComponentModel;
+using Mono.Xml.Schema;
 
 namespace System.Xml.Schema
 {
@@ -12,12 +15,33 @@ namespace System.Xml.Schema
 	/// </summary>
 	public class XmlSchemaAny : XmlSchemaParticle
 	{
+		static XmlSchemaAny anyTypeContent;
+		internal static XmlSchemaAny AnyTypeContent {
+			get {
+				if (anyTypeContent == null) {
+					anyTypeContent = new XmlSchemaAny ();
+					anyTypeContent.MaxOccursString = "unbounded";
+					anyTypeContent.MinOccurs = 0;
+					anyTypeContent.CompileOccurence (null, null);
+					anyTypeContent.Namespace = "##any";
+					anyTypeContent.wildcard.HasValueAny = true;
+					anyTypeContent.wildcard.ResolvedNamespaces = new StringCollection ();
+					// Although it is not documented by W3C, but it should be.
+					anyTypeContent.wildcard.ResolvedProcessing =
+					anyTypeContent.ProcessContents = XmlSchemaContentProcessing.Lax;
+				}
+				return anyTypeContent;
+			}
+		}
+
 		private string nameSpace;
 		private XmlSchemaContentProcessing processing;
 		private static string xmlname = "any";
+		private XsdWildcard wildcard;
 
 		public XmlSchemaAny()
 		{
+			wildcard = new XsdWildcard (this);
 		}
 
 		[System.Xml.Serialization.XmlAttribute("namespace")]
@@ -35,6 +59,37 @@ namespace System.Xml.Schema
 			set{ processing = value; }
 		}
 
+		// Internal
+		internal bool HasValueAny {
+			get { return wildcard.HasValueAny; }
+		}
+
+		internal bool HasValueLocal {
+			get { return wildcard.HasValueLocal; }
+		}
+
+		internal bool HasValueOther {
+			get { return wildcard.HasValueOther; }
+		}
+
+		internal bool HasValueTargetNamespace {
+			get { return wildcard.HasValueTargetNamespace; }
+		}
+
+		internal StringCollection ResolvedNamespaces {
+			get { return wildcard.ResolvedNamespaces; }
+		}
+
+		internal XmlSchemaContentProcessing ResolvedProcessContents 
+		{ 
+			get{ return wildcard.ResolvedProcessing; } 
+		}
+
+		internal string TargetNamespace
+		{
+			get { return wildcard.TargetNamespace; }
+		}
+
 		/// <remarks>
 		/// 1. id must be of type ID
 		/// 2. namespace can have one of the following values:
@@ -42,7 +97,7 @@ namespace System.Xml.Schema
 		///		b) list of anyURI and ##targetNamespace and ##local
 		/// </remarks>
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
@@ -51,48 +106,73 @@ namespace System.Xml.Schema
 			errorCount = 0;
 
 			XmlSchemaUtil.CompileID(Id,this, schema.IDCollection,h);
+			wildcard.TargetNamespace = schema.TargetNamespace;
+			if (wildcard.TargetNamespace == null)
+				wildcard.TargetNamespace = "";
+			CompileOccurence (h, schema);
+
+			wildcard.Compile (Namespace, h, schema);
+
+			if (processing == XmlSchemaContentProcessing.None)
+				wildcard.ResolvedProcessing = XmlSchemaContentProcessing.Strict;
+			else
+				wildcard.ResolvedProcessing = processing;
 
-			//define ##any=1,##other=2,##targetNamespace=4,##local=8,anyURI=16
-			int nscount = 0;
-			string[] nslist = XmlSchemaUtil.SplitList(Namespace);
-			foreach(string ns in nslist)
-			{
-				switch(ns)
-				{
-					case "##any": 
-						nscount |= 1;
-						break;
-					case "##other":
-						nscount |= 2;
-						break;
-					case "##targetNamespace":
-						nscount |= 4;
-						break;
-					case "##local":
-						nscount |= 8;
-						break;
-					default:
-						if(!XmlSchemaUtil.CheckAnyUri(ns))
-							error(h,"the namespace is not a valid anyURI");
-						else
-							nscount |= 16;
-						break;
-				}
-			}
-			if((nscount&1) == 1 && nscount != 1)
-				error(h,"##any if present must be the only namespace attribute");
-			if((nscount&2) == 2 && nscount != 2)
-				error(h,"##other if present must be the only namespace attribute");
-			
 			this.CompilationId = schema.CompilationId;
 			return errorCount;
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
 			return errorCount;
 		}
+
+		// 3.8.6. Attribute Wildcard Intersection
+		// Only try to examine if their intersection is expressible, and
+		// returns if the result is empty.
+		internal bool ExamineAttributeWildcardIntersection (XmlSchemaAny other,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			return wildcard.ExamineAttributeWildcardIntersection (other, h, schema);
+		}
+
+		internal override void ValidateDerivationByRestriction (XmlSchemaParticle baseParticle, 
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			// TODO
+		}
+
+
+		internal override void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema)
+		{
+			// do nothing
+		}
+
+		internal override void ValidateUniqueParticleAttribution (
+			XmlSchemaObjectTable qnames, ArrayList nsNames,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			// Wildcard Intersection check.
+			foreach (XmlSchemaAny other in nsNames)
+				if (!ExamineAttributeWildcardIntersection (other, h, schema))
+					error (h, "Ambiguous -any- particle was found.");
+			nsNames.Add (this);
+		}
+
+		internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			// do nothing
+		}
+
+		// 3.10.4 Wildcard Allows Namespace Name. (In fact it is almost copy...)
+		internal bool ValidateWildcardAllowsNamespaceName (string ns,
+			ValidationEventHandler h, XmlSchema schema, bool raiseError)
+		{
+			return wildcard.ValidateWildcardAllowsNamespaceName (ns, h, schema, raiseError);
+		}
+
 		//<any
 		//  id = ID
 		//  maxOccurs =  (nonNegativeInteger | unbounded)  : 1

+ 94 - 34
mcs/class/System.XML/System.Xml.Schema/XmlSchemaAnyAttribute.cs

@@ -1,9 +1,12 @@
 // Author: Dwivedi, Ajay kumar
 //            [email protected]
 using System;
+using System.Collections;
+using System.Collections.Specialized;
 using System.Xml;
 using System.ComponentModel;
 using System.Xml.Serialization;
+using Mono.Xml.Schema;
 
 namespace System.Xml.Schema
 {
@@ -15,9 +18,11 @@ namespace System.Xml.Schema
 		private string nameSpace;
 		private XmlSchemaContentProcessing processing;
 		private static string xmlname = "anyAttribute";
+		private XsdWildcard wildcard;
 
 		public XmlSchemaAnyAttribute()
 		{
+			wildcard = new XsdWildcard (this);
 		}
 
 		[System.Xml.Serialization.XmlAttribute("namespace")]
@@ -35,6 +40,37 @@ namespace System.Xml.Schema
 			set{ processing = value; }
 		}
 
+		// Internal
+		internal bool HasValueAny {
+			get { return wildcard.HasValueAny; }
+		}
+
+		internal bool HasValueLocal {
+			get { return wildcard.HasValueLocal; }
+		}
+
+		internal bool HasValueOther {
+			get { return wildcard.HasValueOther; }
+		}
+
+		internal bool HasValueTargetNamespace {
+			get { return wildcard.HasValueTargetNamespace; }
+		}
+
+		internal StringCollection ResolvedNamespaces {
+			get { return wildcard.ResolvedNamespaces; }
+		}
+
+		internal XmlSchemaContentProcessing ResolvedProcessContents 
+		{ 
+			get{ return wildcard.ResolvedProcessing; } 
+		}
+
+		internal string TargetNamespace
+		{
+			get { return wildcard.TargetNamespace; }
+		}
+
 		/// <remarks>
 		/// 1. id must be of type ID
 		/// 2. namespace can have one of the following values:
@@ -42,7 +78,7 @@ namespace System.Xml.Schema
 		///		b) list of anyURI and ##targetNamespace and ##local
 		/// </remarks>
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
@@ -50,50 +86,74 @@ namespace System.Xml.Schema
 
 			errorCount = 0;
 
+			wildcard.TargetNamespace = schema.TargetNamespace;
+			if (wildcard.TargetNamespace == null)
+				wildcard.TargetNamespace = "";
+
 			XmlSchemaUtil.CompileID(Id,this, schema.IDCollection,h);
 
-			//define ##any=1,##other=2,##targetNamespace=4,##local=8,anyURI=16
-			int nscount = 0;
-			string[] nslist = XmlSchemaUtil.SplitList(Namespace);
-			foreach(string ns in nslist)
-			{
-				switch(ns)
-				{
-					case "##any": 
-						nscount |= 1;
-						break;
-					case "##other":
-						nscount |= 2;
-						break;
-					case "##targetNamespace":
-						nscount |= 4;
-						break;
-					case "##local":
-						nscount |= 8;
-						break;
-					default:
-						if(!XmlSchemaUtil.CheckAnyUri(ns))
-							error(h,"the namespace is not a valid anyURI");
-						else
-							nscount |= 16;
-						break;
-				}
-			}
-			if((nscount&1) == 1 && nscount != 1)
-				error(h,"##any if present must be the only namespace attribute");
-			if((nscount&2) == 2 && nscount != 2)
-				error(h,"##other if present must be the only namespace attribute");
-			
+			wildcard.Compile (Namespace, h, schema);
+
+			if (processing == XmlSchemaContentProcessing.None)
+				wildcard.ResolvedProcessing = XmlSchemaContentProcessing.Strict;
+			else
+				wildcard.ResolvedProcessing = processing;
+
 			this.CompilationId = schema.CompilationId;
 			return errorCount;
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
 			return errorCount;
 		}
 
+		// 3.10.6 Wildcard Subset
+		internal void ValidateWildcardSubset (XmlSchemaAnyAttribute other,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			wildcard.ValidateWildcardSubset (other, h, schema);
+
+			/*
+			// 1.
+			if (this.hasValueAny)
+				return;
+			if (this.hasValueOther) {
+				if (other.hasValueOther) {
+					// 2.1 and 2.2
+					if (this.targetNamespace == other.targetNamespace ||
+						other.targetNamespace == null || other.targetNamespace == "")
+						return;
+				}
+				// 3.2.2
+				else if (this.targetNamespace == null || targetNamespace == String.Empty)
+					return;
+				else {
+					foreach (string ns in other.resolvedNamespaces)
+						if (ns == this.targetNamespace) {
+							error (h, "Invalid wildcard subset was found.");
+							return;
+						}
+				}
+			} else {
+				// 3.1
+				if (!this.hasValueLocal && other.hasValueLocal) {
+					error (h, "Invalid wildcard subset was found.");
+				} else if (other.resolvedNamespaces.Count == 0)
+					return;
+				else {
+					ArrayList al = new ArrayList (this.resolvedNamespaces);
+					foreach (string ns in other.resolvedNamespaces)
+						if (!al.Contains (ns)) {
+							error (h, "Invalid wildcard subset was found.");
+							return;
+						}
+				}
+			}
+			*/
+		}
+
 		//<anyAttribute
 		//  id = ID
 		//  namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )  : ##any

+ 134 - 48
mcs/class/System.XML/System.Xml.Schema/XmlSchemaAttribute.cs

@@ -1,5 +1,10 @@
-// Author: Dwivedi, Ajay kumar
-//            [email protected]
+//
+// System.Xml.Schema.XmlSchemaAttribute.cs
+//
+// Authors:
+//	Dwivedi, Ajay kumar  [email protected]
+//	Enomoto, Atsushi     [email protected]
+//
 using System;
 using System.Xml;
 using System.ComponentModel;
@@ -15,15 +20,19 @@ namespace System.Xml.Schema
 		private object attributeType;
 		private string defaultValue;
 		private string fixedValue;
+		private string validatedDefaultValue;
+		private string validatedFixedValue;
 		private XmlSchemaForm form;
 		private string name;
+		private string targetNamespace;
 		private XmlQualifiedName qualifiedName;
 		private XmlQualifiedName refName;
 		private XmlSchemaSimpleType schemaType;
 		private XmlQualifiedName schemaTypeName;
 		private XmlSchemaUse use;
 		//Compilation fields
-		internal bool parentIsSchema = false;
+		internal bool ParentIsSchema = false;
+		private XmlSchemaAttribute referencedAttribute;
 		private static string xmlname = "attribute";
 
 		public XmlSchemaAttribute()
@@ -122,8 +131,27 @@ namespace System.Xml.Schema
 
 		[XmlIgnore]
 		public object AttributeType 
-		{ //FIXME: This is not correct. Is it?
-			get{ return attributeType; }
+		{
+			get{
+				if (referencedAttribute != null)
+					return referencedAttribute.AttributeType;
+				else
+					return attributeType;
+			}
+		}
+
+		// Post compilation default value (normalized)
+		internal string ValidatedDefaultValue
+		{
+			// DefaultValue can be overriden in case of ref.
+			get { return validatedDefaultValue; }
+		}
+
+		// Post compilation fixed value (normalized)
+		internal string ValidatedFixedValue 
+		{
+			// FixedValue can be overriden in case of ref.
+			get { return validatedFixedValue; }
 		}
 
 		#endregion
@@ -168,7 +196,7 @@ namespace System.Xml.Schema
 		///     4. If default and use are both present, use must have the ·actual value· optional.
 		/// </remarks>
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
@@ -176,7 +204,7 @@ namespace System.Xml.Schema
 
 			errorCount = 0;
 			
-			if(parentIsSchema)//a
+			if(ParentIsSchema || isRedefineChild)//a
 			{
 				if(RefName!= null && !RefName.IsEmpty) // a.1
 					error(h,"ref must be absent in the top level <attribute>");
@@ -187,6 +215,8 @@ namespace System.Xml.Schema
 				if(Use != XmlSchemaUse.None)		// a.3
 					error(h,"use must be absent in the top level <attribute>");
 
+				targetNamespace = schema.TargetNamespace;
+
 				// TODO: a.10, a.11, a.12, a.13
 				CompileCommon(h, schema, true);
 			}
@@ -195,6 +225,11 @@ namespace System.Xml.Schema
 				//FIXME: How to Use of AttributeFormDefault????
 				if(RefName == null || RefName.IsEmpty)
 				{
+					if(form == XmlSchemaForm.Qualified || (form == XmlSchemaForm.None && schema.AttributeFormDefault == XmlSchemaForm.Qualified))
+						this.targetNamespace = schema.TargetNamespace;
+					else
+						this.targetNamespace = "";
+
 					//TODO: b.8
 					CompileCommon(h, schema, true);
 				}
@@ -208,6 +243,7 @@ namespace System.Xml.Schema
 						error(h,"simpletype must be absent if ref is present");
 					if(this.schemaTypeName != null && !this.schemaTypeName.IsEmpty)
 						error(h,"type must be absent if ref is present");
+
 					CompileCommon(h, schema, false);
 				}
 			}
@@ -227,7 +263,7 @@ namespace System.Xml.Schema
 				else if(Name == "xmlns") // a.14 , b5
 					error(h,"attribute name must not be xmlns");
 				else
-					qualifiedName = new XmlQualifiedName(Name, schema.TargetNamespace);	
+					qualifiedName = new XmlQualifiedName(Name, targetNamespace);
 
 				if(SchemaType != null)
 				{
@@ -243,7 +279,7 @@ namespace System.Xml.Schema
 			else
 			{
 				if(RefName == null || RefName.IsEmpty) 
-					error(h,"Error: Should Never Happen. refname must be present");
+					throw new NotImplementedException ("Error: Should Never Happen. refname must be present");
 				else
 					qualifiedName = RefName;
 			}
@@ -266,57 +302,107 @@ namespace System.Xml.Schema
 		///			QName, SimpleType, Scope, Default|Fixed, annotation
 		/// </summary>
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h, XmlSchema schema)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
-			if(isCompiled)
+			if(IsValidated (schema.ValidationId))
 				return errorCount;
 
-			//If Parent is schema:
-			if(parentIsSchema)
+			// -- Attribute Declaration Schema Component --
+			// {name}, {target namespace} -> QualifiedName. Already Compile()d.
+			// {type definition} -> attributeType. From SchemaType or SchemaTypeName.
+			// {scope} -> ParentIsSchema | isRedefineChild.
+			// {value constraint} -> ValidatedFixedValue, ValidatedDefaultValue.
+			// {annotation}
+			// -- Attribute Use Schema Component --
+			// {required}
+			// {attribute declaration}
+			// {value constraint}
+
+			// First, fill type information for type reference
+			if (SchemaTypeName != null && SchemaTypeName != XmlQualifiedName.Empty)
 			{
-				if(SchemaType != null)
-				{
-					errorCount += SchemaType.Validate(h, schema);
-					attributeType = SchemaType;
+				// If type is null, then it is missing sub components .
+				XmlSchemaType type = schema.SchemaTypes [SchemaTypeName] as XmlSchemaType;
+				if (type is XmlSchemaComplexType)
+					error(h,"An attribute can't have complexType Content");
+				else if (type != null) {	// simple type
+					errorCount += type.Validate (h, schema);
+					attributeType = type;
 				}
-				else if(SchemaTypeName != null && !SchemaTypeName.IsEmpty)
-				{
-					//First Try to get a Inbuilt DataType
-					XmlSchemaDatatype dtype = XmlSchemaDatatype.FromName(SchemaTypeName);
-					if(dtype != null)
-					{
-						attributeType = dtype;
-					}
-					else
-					{
-						XmlSchemaObject obj = schema.SchemaTypes[SchemaTypeName];
-
-						if(obj is XmlSchemaSimpleType)
-						{
-							XmlSchemaSimpleType stype = (XmlSchemaSimpleType) obj;
-							errorCount += stype.Validate(h, schema);
-							attributeType = stype;
-						}
-						else if(attributeType == null)
-							error(h,"The type '"+ SchemaTypeName +"' is not defined in the schema");
-						else if(attributeType is XmlSchemaComplexType)
-							error(h,"An attribute can't have complexType Content");
-						else
-							error(h, "Should Never Happen. Illegal content in SchemaTypes");
-					}
+				else if (SchemaTypeName == XmlSchemaComplexType.AnyTypeName)
+					attributeType = XmlSchemaComplexType.AnyType;
+				else if (SchemaTypeName.Namespace == XmlSchema.Namespace) {
+					attributeType = XmlSchemaDatatype.FromName (SchemaTypeName);
+					if (attributeType == null)
+						error (h, "Invalid xml schema namespace datatype was specified.");
 				}
-				else
-				{
-					error(h,"Should Never Happen. Attribute SimpleType Not set. Should have been caught in the Compile() phase");
+				// otherwise, it might be missing sub components.
+				else if (!schema.missedSubComponents)
+					error (h, "Referenced schema type " + SchemaTypeName + " was not found in the corresponding schema.");
+				/*
+				attributeType = schema.Schemas.FindSchemaType (SchemaTypeName);
+				if (attributeType == null) {
+					if (SchemaTypeName.Namespace == XmlSchema.Namespace)
+						error (h, "Invalid xml schema namespace datatype was specified.");
+					else if (!schema.missedSubComponents)
+						error (h, "Referenced schema type was not found in the corresponding schema. Schema type name is " + SchemaTypeName + " .");
 				}
+				if (attributeType is XmlSchemaComplexType)
+					error(h,"An attribute can't have complexType Content");
+				XmlSchemaType attrSchemaType = attributeType as XmlSchemaType;
+				if (attrSchemaType != null)
+					attrSchemaType.Validate (h, schema);
+				*/
 			}
-			else
+
+			// Then, fill type information for the type references for the referencing attributes
+			if (RefName != null && RefName != XmlQualifiedName.Empty)
 			{
-				//TODO: Local Attribute Validation
+				referencedAttribute = schema.Attributes [RefName] as XmlSchemaAttribute;
+				// If el is null, then it is missing sub components .
+				if (referencedAttribute != null)
+					errorCount += referencedAttribute.Validate (h, schema);
+				// otherwise, it might be missing sub components.
+				else if (!schema.missedSubComponents)
+					error (h, "Referenced attribute " + RefName + " was not found in the corresponding schema.");
 			}
-			isCompiled = true;
+
+			if (attributeType == null)
+				attributeType = XmlSchemaSimpleType.AnySimpleType;
+
+			// Validate {value constraints}
+			if (defaultValue != null || fixedValue != null) {
+				XmlSchemaDatatype datatype = attributeType as XmlSchemaDatatype;
+				if (datatype == null)
+					datatype = ((XmlSchemaSimpleType) attributeType).Datatype;
+				if (datatype.TokenizedType == XmlTokenizedType.QName)
+					error (h, "By the defection of the W3C XML Schema specification, it is impossible to supply QName default or fixed values.");
+				else {
+					try {
+						if (defaultValue != null) {
+							validatedDefaultValue = datatype.Normalize (defaultValue);
+							datatype.ParseValue (validatedDefaultValue, null, null);
+						}
+					} catch (Exception ex) {
+						// FIXME: This is not a good way to handle exception.
+						error (h, "The Attribute's default value is invalid with its type definition.", ex);
+					}
+					try {
+						if (fixedValue != null) {
+							validatedFixedValue = datatype.Normalize (fixedValue);
+							datatype.ParseValue (validatedFixedValue, null, null);
+						}
+					} catch (Exception ex) {
+						// FIXME: This is not a good way to handle exception.
+						error (h, "The Attribute's fixed value is invalid with its type definition.", ex);
+					}
+				}
+			}
+
+			ValidationId = schema.ValidationId;
 			return errorCount;
 		}
+
 		//<attribute
 		//  default = string
 		//  fixed = string

+ 64 - 10
mcs/class/System.XML/System.Xml.Schema/XmlSchemaAttributeGroup.cs

@@ -1,6 +1,12 @@
-// Author: Dwivedi, Ajay kumar
-//            [email protected]
+//
+// System.Xml.Schema.XmlSchemaAttributeGroup.cs
+//
+// Authors:
+//	Dwivedi, Ajay kumar  [email protected]
+//	Enomoto, Atsushi     [email protected]
+//
 using System;
+using System.Collections;
 using System.Xml.Serialization;
 using System.Xml;
 
@@ -11,12 +17,14 @@ namespace System.Xml.Schema
 	/// </summary>
 	public class XmlSchemaAttributeGroup : XmlSchemaAnnotated
 	{
-		private XmlSchemaAnyAttribute any;
+		private XmlSchemaAnyAttribute anyAttribute;
 		private XmlSchemaObjectCollection attributes;
 		private string name;
 		private XmlSchemaAttributeGroup redefined;
 		private XmlQualifiedName qualifiedName;
 		private static string xmlname = "attributeGroup";
+		private XmlSchemaObjectTable attributeUses;
+		private XmlSchemaAnyAttribute anyAttributeUse;
 
 		public XmlSchemaAttributeGroup()
 		{
@@ -37,11 +45,20 @@ namespace System.Xml.Schema
 			get{ return attributes;}
 		}
 
+		internal XmlSchemaObjectTable AttributeUses
+		{
+			get { return attributeUses; }
+		}
+		internal XmlSchemaAnyAttribute AnyAttributeUse
+		{
+			get { return anyAttributeUse; }
+		}
+
 		[XmlElement("anyAttribute",Namespace=XmlSchema.Namespace)]
 		public XmlSchemaAnyAttribute AnyAttribute 
 		{
-			get{ return any;}
-			set{ any = value;}
+			get{ return anyAttribute;}
+			set{ anyAttribute = value;}
 		}
 
 		//Undocumented property
@@ -63,17 +80,24 @@ namespace System.Xml.Schema
 		///  1. Name must be present
 		/// </remarks>
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
+			// FIXME: Even if it was already compiled, it should check recursion.
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
-				return 0;
+				return errorCount;
 
 			errorCount = 0;
 
+			if (redefinedObject != null) {
+				errorCount += redefined.Compile (h, schema);
+				if (errorCount == 0)
+					redefined = (XmlSchemaAttributeGroup) redefinedObject;
+			}
+
 			XmlSchemaUtil.CompileID(Id,this, schema.IDCollection,h);
 
-			if(this.Name == null) //1
+			if(this.Name == null || this.Name == String.Empty) //1
 				error(h,"Name is required in top level simpletype");
 			else if(!XmlSchemaUtil.CheckNCName(this.Name)) // b.1.2
 				error(h,"name attribute of a simpleType must be NCName");
@@ -105,10 +129,40 @@ namespace System.Xml.Schema
 			this.CompilationId = schema.CompilationId;
 			return errorCount;
 		}
-		
+
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
+			if (IsValidated (schema.CompilationId))
+				return errorCount;
+
+			if (redefined == null && redefinedObject != null) {
+				redefinedObject.Compile (h, schema);
+				redefined = (XmlSchemaAttributeGroup) redefinedObject;
+				redefined.Validate (h, schema);
+			}
+
+			XmlSchemaObjectCollection actualAttributes = null;
+			/*
+			if (this.redefined != null) {
+				actualAttributes = new XmlSchemaObjectCollection ();
+				foreach (XmlSchemaObject obj in Attributes) {
+					XmlSchemaAttributeGroupRef grp = obj as XmlSchemaAttributeGroupRef;
+					if (grp != null && grp.QualifiedName == this.QualifiedName)
+						actualAttributes.Add (redefined);
+					else
+						actualAttributes.Add (obj);
+				}
+			}
+			else
+			*/
+				actualAttributes = Attributes;
+
+			attributeUses = new XmlSchemaObjectTable ();
+			errorCount += XmlSchemaUtil.ValidateAttributesResolved (attributeUses,
+				h, schema, actualAttributes, AnyAttribute, 
+				ref anyAttributeUse, redefined);
+			ValidationId = schema.ValidationId;
 			return errorCount;
 		}
 

+ 2 - 2
mcs/class/System.XML/System.Xml.Schema/XmlSchemaAttributeGroupRef.cs

@@ -31,7 +31,7 @@ namespace System.Xml.Schema
 		/// 2. The element must be empty. ?? FIXME: Is this correct or annotation is permitted?
 		/// </remarks>
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
@@ -53,7 +53,7 @@ namespace System.Xml.Schema
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
 			return errorCount;
 		}

+ 109 - 26
mcs/class/System.XML/System.Xml.Schema/XmlSchemaChoice.cs

@@ -1,6 +1,12 @@
-// Author: Dwivedi, Ajay kumar
-//            [email protected]
+//
+// System.Xml.Schema.XmlSchemaChoice.cs
+//
+// Author:
+//	Dwivedi, Ajay kumar  [email protected]
+//	Atsushi Enomoto  [email protected]
+//
 using System;
+using System.Collections;
 using System.Xml.Serialization;
 using System.Xml;
 
@@ -12,7 +18,9 @@ namespace System.Xml.Schema
 	public class XmlSchemaChoice : XmlSchemaGroupBase
 	{
 		private XmlSchemaObjectCollection items;
+		private XmlSchemaObjectCollection compiledItems;
 		private static string xmlname = "choice";
+		private decimal minEffectiveTotalRange = -1;
 
 		public XmlSchemaChoice()
 		{
@@ -28,52 +36,127 @@ namespace System.Xml.Schema
 		{
 			get{ return items; }
 		}
+		internal XmlSchemaObjectCollection CompiledItems 
+		{
+			get{ return compiledItems; }
+		}
 
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
 				return 0;
 
-			//FIXME: Should we reset the values
-			if(MinOccurs > MaxOccurs)
-				error(h,"minOccurs must be less than or equal to maxOccurs");
-
 			XmlSchemaUtil.CompileID(Id, this, schema.IDCollection, h);
+			CompileOccurence (h, schema);
 
 			foreach(XmlSchemaObject obj in Items)
 			{
-				if(obj is XmlSchemaElement)
-				{
-					errorCount += ((XmlSchemaElement)obj).Compile(h, schema);
-				}
-				else if(obj is XmlSchemaGroupRef)
-				{
-					errorCount += ((XmlSchemaGroupRef)obj).Compile(h,schema);
-				}
-				else if(obj is XmlSchemaChoice)
-				{
-					errorCount += ((XmlSchemaChoice)obj).Compile(h,schema);
-				}
-				else if(obj is XmlSchemaSequence)
-				{
-					errorCount += ((XmlSchemaSequence)obj).Compile(h,schema);
-				}
-				else if(obj is XmlSchemaAny)
+				if(obj is XmlSchemaElement ||
+					obj is XmlSchemaGroupRef ||
+					obj is XmlSchemaChoice ||
+					obj is XmlSchemaSequence ||
+					obj is XmlSchemaAny)
 				{
-					errorCount += ((XmlSchemaAny)obj).Compile(h,schema);
+					errorCount += obj.Compile(h,schema);
 				}
+				else
+					error(h, "Invalid schema object was specified in the particles of the choice model group.");
 			}
 			this.CompilationId = schema.CompilationId;
 			return errorCount;
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
+			if (IsValidated (schema.CompilationId))
+				return errorCount;
+
+			compiledItems = new XmlSchemaObjectCollection ();
+			foreach (XmlSchemaObject obj in Items) {
+				errorCount += obj.Validate (h, schema);
+				compiledItems.Add (obj);
+			}
+
+			ValidationId = schema.ValidationId;
 			return errorCount;
 		}
+
+		internal override void ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			XmlSchemaAny any = baseParticle as XmlSchemaAny;
+			if (any != null) {
+				// NSRecurseCheckCardinality
+				this.ValidateNSRecurseCheckCardinality (any, h, schema);
+				return;
+			}
+
+			XmlSchemaChoice choice = baseParticle as XmlSchemaChoice;
+			if (choice != null) {
+				// RecurseLax
+				this.ValidateOccurenceRangeOK (choice, h, schema);
+
+				// FIXME: What is the correct "order preserving" mapping?
+				int baseIndex = 0;
+				for (int i = 0; i < this.Items.Count; i++) {
+					XmlSchemaParticle pd = Items [i] as XmlSchemaParticle;
+					if (choice.Items.Count > baseIndex) {
+						XmlSchemaParticle pb = choice.Items [baseIndex] as XmlSchemaParticle;
+						pd.ActualParticle.ValidateDerivationByRestriction (pb.ActualParticle, h, schema);
+						baseIndex++;
+					}
+					else
+						error (h, "Invalid choice derivation by extension was found.");
+				}
+
+				return;
+			}
+
+			error (h, "Invalid choice derivation by restriction was found.");
+		}
+
+		internal override decimal GetMinEffectiveTotalRange ()
+		{
+			if (minEffectiveTotalRange >= 0)
+				return minEffectiveTotalRange;
+
+			decimal product = 0; //this.ValidatedMinOccurs;
+			if (Items.Count == 0)
+				product = 0;
+			else {
+				foreach (XmlSchemaParticle p in this.Items) {
+					decimal got = p.GetMinEffectiveTotalRange ();
+					if (product > got)
+						product= got;
+				}
+			}
+			minEffectiveTotalRange = product;
+			return product;
+		}
+
+		internal override void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema)
+		{
+			foreach (XmlSchemaParticle p in this.Items)
+				p.CheckRecursion (depth, h, schema);
+		}
+
+		internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames, ArrayList nsNames,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			foreach (XmlSchemaParticle p in this.Items)
+				p.ValidateUniqueParticleAttribution (qnames, nsNames, h, schema);
+		}
+
+		internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			foreach (XmlSchemaParticle p in this.Items)
+				p.ValidateUniqueTypeAttribution (labels, h, schema);
+		}
+
 		//<choice
 		//  id = ID
 		//  maxOccurs =  (nonNegativeInteger | unbounded)  : 1

+ 74 - 10
mcs/class/System.XML/System.Xml.Schema/XmlSchemaCollection.cs

@@ -1,5 +1,10 @@
-// Author: Dwivedi, Ajay kumar
-//            [email protected]
+//
+// System.Xml.Schema.XmlSchemaCollection.cs
+//
+// Authors:
+//	Dwivedi, Ajay kumar  [email protected]
+//	Atsushi Enomoto      [email protected]
+//
 using System;
 using System.Collections;
 using System.Xml;
@@ -16,6 +21,7 @@ namespace System.Xml.Schema
 		private Hashtable htable;
 		private Hashtable uriTable;
 		private XmlNameTable ntable;
+		internal Guid CompilationId;
 
 		public XmlSchemaCollection()
 			: this (new NameTable ())
@@ -27,6 +33,7 @@ namespace System.Xml.Schema
 			htable = new Hashtable();
 			uriTable = new Hashtable ();
 			ntable = nametable;
+			CompilationId = Guid.NewGuid ();
 		}
 
 		//properties
@@ -56,8 +63,7 @@ namespace System.Xml.Schema
 		public event ValidationEventHandler ValidationEventHandler;
 
 		// Methods
-		[MonoTODO]
-		public XmlSchema Add(string ns, XmlReader reader)
+		public XmlSchema Add (string ns, XmlReader reader)
 		{
 			if (reader == null)
 				throw new ArgumentNullException ("reader");
@@ -66,21 +72,25 @@ namespace System.Xml.Schema
 			return Add (schema);
 		}
 
-		[MonoTODO]
 		public XmlSchema Add(string ns, string uri)
 		{
-			if (uri == null || uri == String.Empty)
-				throw new ArgumentNullException ("uri");
-
 			return Add (ns, new XmlTextReader (uri));
 		}
 
-		[MonoTODO]
 		public XmlSchema Add(XmlSchema schema)
 		{
 			if (schema == null)
 				throw new ArgumentNullException ("schema");
 
+			if (!schema.IsCompiled)
+				schema.Compile (null, this);
+			/*
+			// This is requried to complete maybe missing sub components.
+			foreach (XmlSchema existing in htable.Values)
+				if (existing.CompilationId != this.CompilationId)
+					existing.Compile (null, this);
+			*/
+
 			htable [GetSafeNs(schema.TargetNamespace)] = schema;
 			return schema;
 		}
@@ -117,7 +127,7 @@ namespace System.Xml.Schema
 			return new XmlSchemaCollectionEnumerator(this);
 		}
 		
-		//assembly Methods
+		// interface Methods
 		[MonoTODO]
 		void ICollection.CopyTo(Array array, int index)
 		{
@@ -135,5 +145,59 @@ namespace System.Xml.Schema
 		{
 			get { return this; }
 		}
+
+		// Internal Methods
+		internal XmlSchemaAttribute FindAttribute (XmlQualifiedName qname)
+		{
+			XmlSchemaAttribute found = null;
+			XmlSchema target = this [qname.Namespace];
+			if (target != null)
+				found = target.Attributes [qname] as XmlSchemaAttribute;
+			if (found != null)
+				return found;
+			foreach (XmlSchema schema in htable.Values) {
+				found = schema.Attributes [qname] as XmlSchemaAttribute;
+				if (found != null)
+					return found;
+			}
+			return null;
+		}
+
+		internal XmlSchemaElement FindElement (XmlQualifiedName qname)
+		{
+			XmlSchemaElement found = null;
+			XmlSchema target = this [qname.Namespace];
+			if (target != null)
+				found = target.Elements [qname] as XmlSchemaElement;
+			if (found != null)
+				return found;
+			foreach (XmlSchema schema in htable.Values) {
+				found = schema.Elements [qname] as XmlSchemaElement;
+				if (found != null)
+					return found;
+			}
+			return null;
+		}
+
+		internal object FindSchemaType (XmlQualifiedName qname)
+		{
+			if (qname == XmlSchemaComplexType.AnyTypeName)
+				return XmlSchemaComplexType.AnyType;
+			else if (qname.Namespace == XmlSchema.Namespace)
+				return XmlSchemaDatatype.FromName (qname);
+
+			XmlSchemaType found = null;
+			XmlSchema target = this [qname.Namespace];
+			if (target != null)
+				found = target.SchemaTypes [qname] as XmlSchemaType;
+			if (found != null)
+				return found;
+			foreach (XmlSchema schema in htable.Values) {
+				found = schema.SchemaTypes [qname] as XmlSchemaType;
+				if (found != null)
+					return found;
+			}
+			return null;
+		}
 	}
 }

+ 22 - 4
mcs/class/System.XML/System.Xml.Schema/XmlSchemaComplexContent.cs

@@ -1,5 +1,10 @@
-// Author: Dwivedi, Ajay kumar
-//            [email protected]
+//
+// System.Xml.Schema.XmlSchemaComplexContent.cs
+//
+// Author:
+//	Dwivedi, Ajay kumar  [email protected]
+//	Atsushi Enomoto  [email protected]
+//
 using System;
 using System.Xml.Serialization;
 using System.Xml;
@@ -37,12 +42,19 @@ namespace System.Xml.Schema
 		/// 1. Content must be present
 		/// </remarks>
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
 				return 0;
 
+			if (isRedefinedComponent) {
+				if (Annotation != null)
+					Annotation.isRedefinedComponent = true;
+				if (Content != null)
+					Content.isRedefinedComponent = true;
+			}
+
 			if(Content == null)
 			{
 				error(h, "Content must be present in a complexContent");
@@ -70,8 +82,14 @@ namespace System.Xml.Schema
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
+			if (IsValidated (schema.ValidationId))
+				return errorCount;
+
+			errorCount += Content.Validate (h, schema);
+
+			ValidationId = schema.ValidationId;
 			return errorCount;
 		}
 		//<complexContent

+ 34 - 5
mcs/class/System.XML/System.Xml.Schema/XmlSchemaComplexContentExtension.cs

@@ -1,5 +1,10 @@
-// Author: Dwivedi, Ajay kumar
-//            [email protected]
+//
+// System.Xml.Schema.XmlSchemaComplexContentExtension.cs
+//
+// Author:
+//	Dwivedi, Ajay kumar  [email protected]
+//	Atsushi Enomoto  [email protected]
+//
 using System;
 using System.Xml;
 using System.Xml.Serialization;
@@ -57,15 +62,26 @@ namespace System.Xml.Schema
 		/// <remarks>
 		/// </remarks>
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
 				return 0;
 
+			if (this.isRedefinedComponent) {
+				if (Annotation != null)
+					Annotation.isRedefinedComponent = true;
+				if (AnyAttribute != null)
+					AnyAttribute.isRedefinedComponent  = true;
+				foreach (XmlSchemaObject obj in Attributes)
+					obj.isRedefinedComponent  = true;
+				if (Particle != null)
+					Particle.isRedefinedComponent  = true;
+			}
+
 			if(BaseTypeName == null || BaseTypeName.IsEmpty)
 			{
-				error(h, "base must be present and a QName");
+				error(h, "base must be present, as a QName");
 			}
 			else if(!XmlSchemaUtil.CheckQName(BaseTypeName))
 				error(h,"BaseTypeName is not a valid XmlQualifiedName");
@@ -109,6 +125,8 @@ namespace System.Xml.Schema
 				{
 					errorCount += ((XmlSchemaSequence)Particle).Compile(h, schema);
 				}
+				else
+					error (h, "Particle of a restriction is limited only to group, sequence, choice and all.");
 			}
 			
 			XmlSchemaUtil.CompileID(Id,this, schema.IDCollection,h);
@@ -118,8 +136,19 @@ namespace System.Xml.Schema
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
+			if (IsValidated (schema.ValidationId))
+				return errorCount;
+
+			if (AnyAttribute != null)
+				errorCount += AnyAttribute.Validate (h, schema);
+			foreach (XmlSchemaObject attrObj in Attributes)
+				errorCount += attrObj.Validate (h, schema);
+			if (Particle != null)
+				errorCount += Particle.Validate (h, schema);
+
+			ValidationId = schema.ValidationId;
 			return errorCount;
 		}
 		//<extension

+ 23 - 5
mcs/class/System.XML/System.Xml.Schema/XmlSchemaComplexContentRestriction.cs

@@ -1,5 +1,10 @@
-// Author: Dwivedi, Ajay kumar
-//            [email protected]
+//
+// System.Xml.Schema.XmlSchemaComplexContentRestriction.cs
+//
+// Author:
+//	Dwivedi, Ajay kumar  [email protected]
+//	Atsushi Enomoto  [email protected]
+//
 using System;
 using System.Xml;
 using System.Xml.Serialization;
@@ -58,15 +63,26 @@ namespace System.Xml.Schema
 		/// 1. base must be present
 		/// </remarks>
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
 				return 0;
 
+			if (this.isRedefinedComponent) {
+				if (Annotation != null)
+					Annotation.isRedefinedComponent = true;
+				if (AnyAttribute != null)
+					AnyAttribute.isRedefinedComponent = true;
+				foreach (XmlSchemaObject obj in Attributes)
+					obj.isRedefinedComponent = true;
+				if (Particle != null)
+					Particle.isRedefinedComponent = true;
+			}
+
 			if(BaseTypeName == null || BaseTypeName.IsEmpty)
 			{
-				error(h, "base must be present and a QName");
+				error(h, "base must be present, as a QName");
 			}
 			else if(!XmlSchemaUtil.CheckQName(BaseTypeName))
 				error(h,"BaseTypeName is not a valid XmlQualifiedName");
@@ -110,6 +126,8 @@ namespace System.Xml.Schema
 				{
 					errorCount += ((XmlSchemaSequence)Particle).Compile(h, schema);
 				}
+				else
+					error (h, "Particle of a restriction is limited only to group, sequence, choice and all.");
 			}
 			
 			XmlSchemaUtil.CompileID(Id,this, schema.IDCollection,h);
@@ -119,7 +137,7 @@ namespace System.Xml.Schema
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
 			return errorCount;
 		}

+ 556 - 67
mcs/class/System.XML/System.Xml.Schema/XmlSchemaComplexType.cs

@@ -6,6 +6,7 @@
 //	Enomoto, Atsushi     [email protected]
 //
 using System;
+using System.Collections;
 using System.Xml;
 using System.ComponentModel;
 using System.Xml.Serialization;
@@ -28,8 +29,11 @@ namespace System.Xml.Schema
 		private bool isAbstract;
 		private bool isMixed;
 		private XmlSchemaParticle particle;
-		
-		internal bool istoplevel = false;
+		private XmlSchemaContentType resolvedContentType;
+
+		internal bool ValidatedIsAbstract;
+		internal bool ParentIsSchema = false;
+
 		private static string xmlname = "complexType";
 
 		private static XmlSchemaComplexType anyType;
@@ -38,14 +42,19 @@ namespace System.Xml.Schema
 			get {
 				if (anyType == null) {
 					anyType = new XmlSchemaComplexType ();
-					anyType.Name = "";
-					anyType.QNameInternal = XmlQualifiedName.Empty;
-					anyType.contentTypeParticle = XmlSchemaParticle.Empty;
+					anyType.Name = "";	// In MS.NET, it is not "anyType"
+					anyType.QNameInternal = XmlQualifiedName.Empty;	// Not xs:anyType as well.
+					anyType.contentTypeParticle = XmlSchemaAny.AnyTypeContent;
+//					anyType.baseSchemaTypeInternal = anyType;
+					anyType.datatypeInternal = XmlSchemaSimpleType.AnySimpleType;
+					anyType.isMixed = true;
 				}
 				return anyType;
 			}
 		}
 
+		internal static readonly XmlQualifiedName AnyTypeName = new XmlQualifiedName ("anyType", XmlSchema.Namespace);
+
 		public XmlSchemaComplexType()
 		{
 			attributes = new XmlSchemaObjectCollection();
@@ -113,29 +122,16 @@ namespace System.Xml.Schema
 			get{ return  anyAttribute; }
 			set{ anyAttribute = value; }
 		}
-
 		#endregion
 
 		#region XmlIgnore
 		[XmlIgnore]
 		public XmlSchemaContentType ContentType 
 		{
-			get{
-				XmlSchemaComplexContent xcc = 
-					ContentModel as XmlSchemaComplexContent;
-				if (xcc != null && xcc.IsMixed)
-					return XmlSchemaContentType.Mixed;
-
-				XmlSchemaSimpleContent xsc = ContentModel as XmlSchemaSimpleContent;
-				if (xsc != null)
-					return XmlSchemaContentType.TextOnly;
-
-				return ContentTypeParticle != null ?
-					XmlSchemaContentType.ElementOnly :
-					XmlSchemaContentType.Empty;
-			}
+			get{ return resolvedContentType; }
 		}
 		[XmlIgnore]
+		[MonoTODO ("Derivation is not supported yet.")]
 		public XmlSchemaParticle ContentTypeParticle 
 		{
 			get{ return contentTypeParticle; }
@@ -172,14 +168,29 @@ namespace System.Xml.Schema
 		///		
 		/// </remarks>
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
-				return 0;
+				return errorCount;
+
+			ValidatedIsAbstract = isAbstract;
+
+			if (isRedefinedComponent) {
+				if (Annotation != null)
+					Annotation.isRedefinedComponent = true;
+				if (AnyAttribute != null)
+					AnyAttribute.isRedefinedComponent = true;
+				foreach (XmlSchemaObject obj in Attributes)
+					obj.isRedefinedComponent = true;
+				if (ContentModel != null)
+					ContentModel.isRedefinedComponent = true;
+				if (Particle != null)
+					Particle.isRedefinedComponent = true;
+			}
 
 			// block/final resolution
-			if(istoplevel)
+			if(ParentIsSchema || isRedefineChild)
 			{
 				if(this.Name == null || this.Name == string.Empty)
 					error(h,"name must be present in a top level complex type");
@@ -197,7 +208,9 @@ namespace System.Xml.Schema
 					else
 					{
 						//TODO: Check what all is not allowed
-						blockResolved = Block & (XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Restriction);
+						if ((Block & XmlSchemaUtil.ComplexTypeBlockAllowed) != Block)
+							error (h, "Invalid block specification.");
+						blockResolved = Block & XmlSchemaUtil.ComplexTypeBlockAllowed;
 					}
 				}
 				else
@@ -207,24 +220,22 @@ namespace System.Xml.Schema
 						blockResolved = XmlSchemaDerivationMethod.All;
 						break;
 					case XmlSchemaDerivationMethod.None:
-						blockResolved = XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Restriction;
+						blockResolved = XmlSchemaDerivationMethod.Empty;
 						break;
 					default:
-						blockResolved = schema.BlockDefault & (XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Restriction);
+						blockResolved = schema.BlockDefault & XmlSchemaUtil.ComplexTypeBlockAllowed;
 						break;
 					}
 				}
+
 				if(Final != XmlSchemaDerivationMethod.None)
 				{
 					if(Final == XmlSchemaDerivationMethod.All)
-					{
 						finalResolved = XmlSchemaDerivationMethod.All;
-					}
+					else if ((Final & XmlSchemaUtil.FinalAllowed) != Final)
+						error (h, "Invalid final specification.");
 					else
-					{
-						//TODO: Check what all is not allowed
-						finalResolved = Final & (XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Restriction);
-					}
+						finalResolved = Final;
 				}
 				else
 				{
@@ -233,10 +244,10 @@ namespace System.Xml.Schema
 						finalResolved = XmlSchemaDerivationMethod.All;
 						break;
 					case XmlSchemaDerivationMethod.None:
-						finalResolved = XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Restriction;
+						finalResolved = XmlSchemaDerivationMethod.Empty;
 						break;
 					default:
-						finalResolved = schema.FinalDefault & (XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Restriction);
+						finalResolved = schema.FinalDefault & XmlSchemaUtil.FinalAllowed;
 						break;
 					}
 				}
@@ -254,56 +265,45 @@ namespace System.Xml.Schema
 			}
 
 			// Process contents and BaseSchemaType
-			if(ContentModel != null)
+			if(contentModel != null)
 			{
 				if(anyAttribute != null || Attributes.Count != 0 || Particle != null)
 					error(h,"attributes, particles or anyattribute is not allowed if ContentModel is present");
+				errorCount += contentModel.Compile (h, schema);
 
 				XmlQualifiedName baseTypeName = null;
-				if(ContentModel is XmlSchemaSimpleContent)
+				XmlSchemaSimpleContent smodel = ContentModel as XmlSchemaSimpleContent;
+				if(smodel != null)
 				{
-					XmlSchemaSimpleContent smodel = (XmlSchemaSimpleContent)ContentModel;
-					errorCount += smodel.Compile(h,schema);
-
 					XmlSchemaSimpleContentExtension sscx = smodel.Content as XmlSchemaSimpleContentExtension;
 					if (sscx != null)
 						baseTypeName = sscx.BaseTypeName;
 					else {
 						XmlSchemaSimpleContentRestriction sscr = smodel.Content as XmlSchemaSimpleContentRestriction;
-						baseTypeName = sscr.BaseTypeName;
-						if (sscr.BaseType != null) {
-							sscr.BaseType.Compile (h, schema);
-							BaseSchemaTypeInternal = sscr.BaseType;
+						if (sscr != null) {
+							baseTypeName = sscr.BaseTypeName;
+							if (sscr.BaseType != null) {
+								sscr.BaseType.Compile (h, schema);
+								baseSchemaTypeInternal = sscr.BaseType;
+							}
 						}
 					}
+					contentTypeParticle = XmlSchemaParticle.Empty;
 				}
-				else if(ContentModel is XmlSchemaComplexContent)
+				else
 				{
-					XmlSchemaComplexContent cmodel = (XmlSchemaComplexContent)ContentModel;
-					errorCount += cmodel.Compile(h,schema);
-
+					XmlSchemaComplexContent cmodel = (XmlSchemaComplexContent) ContentModel;
 					XmlSchemaComplexContentExtension sccx = cmodel.Content as XmlSchemaComplexContentExtension;
 					if (sccx != null) {
 						contentTypeParticle = sccx.Particle;
 						baseTypeName = sccx.BaseTypeName;
 					}
 					else {
-						XmlSchemaComplexContentRestriction sccr = cmodel.Content as XmlSchemaComplexContentRestriction;
-						contentTypeParticle = sccr.Particle;
-						baseTypeName = sccr.BaseTypeName;
-					}
-				}
-
-				// fill base schema type
-				if (BaseSchemaTypeInternal == null && baseTypeName != null) {	// simple content restriction may have type itself.
-					if (baseTypeName.Namespace == XmlSchema.Namespace)
-						BaseSchemaTypeInternal = XmlSchemaDatatype.FromName (baseTypeName);
-					else {
-						XmlSchema targetSchema = schema.Schemas [baseTypeName.Namespace];
-						if (targetSchema != null)
-							BaseSchemaTypeInternal = schema.SchemaTypes [baseTypeName];
-						if (BaseSchemaTypeInternal == null)
-							schema.MissingBaseSchemaTypeRefs.Add (this, baseTypeName);
+						XmlSchemaComplexContentRestriction sccr = (XmlSchemaComplexContentRestriction) cmodel.Content;
+						if (sccr != null) {
+							contentTypeParticle = sccr.Particle;
+							baseTypeName = sccr.BaseTypeName;
+						}
 					}
 				}
 			}
@@ -356,13 +356,499 @@ namespace System.Xml.Schema
 			this.CompilationId = schema.CompilationId;
 			return errorCount;
 		}
-		
+
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
+			if (IsValidated (schema.ValidationId))
+				return errorCount;
+			// FIXME: omitting it causes StackOverflowException
+			// among the compilation of element and types, but
+			// it may result in insufficient results.
+			ValidationId = schema.ValidationId;
+
+			// Term. 1 of 3.4.6 = 3.4.1 : Complex Type Definitions Properties Correct
+			// Term. 2 and 3 goes ValidateContentModel().
+			// Term. 4 and 5 follows in this method.
+			//
+			// Schema component to CLR type property mapping:
+			// {derivation method} => resolvedDerivedBy
+			// {annotations} are as is.
+			// {name}, {namespace} => QualifiedName
+			// {final} and {prohibited substitutions} are Compile()d.
+			// {abstract} => ValidatedIsAbstract
+
+			// Below are different properties depending on simpleContent | complexContent.
+			// {base type definition} => BaseSchemaType (later)
+			// {attribute uses} => AttributeUses (later)
+			// {content type} => ContentType and ContentTypeParticle (later)
+
+			// TODO: Beware of E1-27 of http://www.w3.org/2001/05/xmlschema-errata#Errata1
+			if (contentModel != null)
+				ValidateContentModel (h, schema);
+			else {
+				if (particle != null)
+					ValidateParticle (h, schema);
+				// contentModel never has them.
+				ValidateImmediateAttributes (h, schema);
+			}
+			// Additional support for 3.8.6 All Group Limited
+			if (contentTypeParticle != null) {
+				XmlSchemaAll termAll = contentTypeParticle.ActualParticle as XmlSchemaAll;
+				if (termAll != null && contentTypeParticle.ValidatedMaxOccurs != 1)
+					error (h, "Particle whose term is -all- and consists of complex type content particle must have maxOccurs = 1.");
+			}
+
+			// {content type} is going to be finished.
+			if (contentTypeParticle == null)
+				contentTypeParticle = XmlSchemaParticle.Empty;
+			contentTypeParticle.ValidateUniqueParticleAttribution (new XmlSchemaObjectTable (),
+				new ArrayList (), h, schema);
+			contentTypeParticle.ValidateUniqueTypeAttribution (
+				new XmlSchemaObjectTable (), h, schema);
+			resolvedContentType = GetContentType ();
+
+			// 3.4.6 Properties Correct :: 5 (Two distinct ID attributes)
+			XmlSchemaAttribute idAttr = null;
+			foreach (XmlSchemaAttribute attr in attributeUses) {
+				XmlSchemaDatatype dt = attr.AttributeType as XmlSchemaDatatype;
+				if (dt != null && dt.TokenizedType != XmlTokenizedType.ID)
+					continue;
+				if (dt == null)
+					dt = ((XmlSchemaSimpleType) attr.AttributeType).Datatype;
+				if (dt != null && dt.TokenizedType == XmlTokenizedType.ID) {
+					if (idAttr != null)
+						error (h, "Two or more ID typed attribute declarations in a complex type are found.");
+					else
+						idAttr = attr;
+				}
+			}
+
+			ValidationId = schema.ValidationId;
 			return errorCount;
 		}
 
+		private void ValidateParticle (ValidationEventHandler h, XmlSchema schema)
+		{
+			// {content type} as a particle.
+			errorCount += particle.Validate (h, schema);
+			contentTypeParticle = Particle;
+			XmlSchemaGroupRef pgrp = Particle as XmlSchemaGroupRef;
+			if (pgrp != null) {
+				if (pgrp.TargetGroup != null)
+					errorCount += pgrp.TargetGroup.Validate (h,schema);
+				// otherwise, it might be missing sub components.
+				else if (!schema.missedSubComponents)// && schema.Schemas [pgrp.RefName.Namespace] != null)
+					error (h, "Referenced group " + pgrp.RefName + " was not found in the corresponding schema.");
+			}
+		}
+
+		private void ValidateImmediateAttributes (ValidationEventHandler h, XmlSchema schema)
+		{
+			// {attribute uses}
+			// also checks 3.4.6 Properties Correct :: 4 (Distinct attributes)
+			attributeUses = new XmlSchemaObjectTable ();
+			XmlSchemaUtil.ValidateAttributesResolved (attributeUses,
+				h, schema, attributes, anyAttribute, ref attributeWildcard, null);
+		}
+
+		private void ValidateContentModel (ValidationEventHandler h, XmlSchema schema)
+		{
+			// Here we check 3.4.6 Properties Correct :: 2. and 3.
+			errorCount += contentModel.Validate (h, schema);
+			XmlSchemaComplexContentExtension cce = contentModel.Content as XmlSchemaComplexContentExtension;
+			XmlSchemaComplexContentRestriction ccr = contentModel.Content as XmlSchemaComplexContentRestriction;
+			XmlSchemaSimpleContentExtension sce = contentModel.Content as XmlSchemaSimpleContentExtension;
+			XmlSchemaSimpleContentRestriction scr = contentModel.Content as XmlSchemaSimpleContentRestriction;
+
+			XmlSchemaAnyAttribute localAnyAttribute = null;
+			XmlSchemaAnyAttribute baseAnyAttribute = null;
+
+			XmlQualifiedName baseTypeName = null;
+			if (cce != null)
+				baseTypeName = cce.BaseTypeName;
+			else if (ccr != null)
+				baseTypeName = ccr.BaseTypeName;
+			else if (sce != null)
+				baseTypeName = sce.BaseTypeName;
+			else
+				baseTypeName = scr.BaseTypeName;
+
+			XmlSchemaType baseType = schema.SchemaTypes [baseTypeName] as XmlSchemaType;
+			// Resolve redefine.
+			if (this.isRedefineChild && baseType != null && this.QualifiedName == baseTypeName) {
+				baseType = (XmlSchemaType) redefinedObject;
+				if (baseType == null)
+					error (h, "Redefinition base type was not found.");
+				baseType.Validate (h, schema);
+			}
+			// 3.4.6 Properties Correct :: 3. Circular definition prohibited.
+			if (ValidateRecursionCheck ())
+				error (h, "Circular definition of schema types was found.");
+			if (baseType != null) {
+				baseType.Validate (h, schema);
+				// Fill "Datatype" property.
+				this.datatypeInternal = baseType.Datatype;
+			} else if (baseTypeName == XmlSchemaComplexType.AnyTypeName)
+				datatypeInternal = XmlSchemaSimpleType.AnySimpleType;
+			else if (baseTypeName.Namespace == XmlSchema.Namespace) {
+				datatypeInternal = XmlSchemaDatatype.FromName (baseTypeName);
+			}
+
+			// {derivation method}
+			XmlSchemaComplexType baseComplexType = baseType as XmlSchemaComplexType;
+			XmlSchemaSimpleType baseSimpleType = baseType as XmlSchemaSimpleType;
+			if (cce != null || sce != null)
+				resolvedDerivedBy = XmlSchemaDerivationMethod.Extension;
+			else
+				resolvedDerivedBy = XmlSchemaDerivationMethod.Restriction;
+
+			// 3.4.6 Derivation Valid (common to Extension and Restriction, Complex) :: 1.
+			if (baseType != null && (baseType.FinalResolved & resolvedDerivedBy) != 0)
+					error (h, "Specified derivation is specified as final by derived schema type.");
+
+			// 3.4.6 Properties Correct :: 2.
+			// Simple {base type definition} and restriction {derivation method} not allowed.
+			if (baseSimpleType != null && resolvedDerivedBy == XmlSchemaDerivationMethod.Restriction)
+				error (h, "If the base schema type is a simple type, then this type must be extension.");
+
+			// Common to complexContent
+			if (cce != null || ccr != null) {
+				// 3.4.3 Complex Type Definition Representation OK :: 1.
+				// base
+				if (baseTypeName == XmlSchemaComplexType.AnyTypeName)
+					baseComplexType = XmlSchemaComplexType.AnyType;
+				else if (baseComplexType == null && !schema.missedSubComponents)
+					error (h, "Referenced base schema type " + baseTypeName + " was not complex type or not found in the corresponding schema.");
+			}
+			// Common to simpleContent 
+			else {
+				// 3.4.3 Complex Type Definition Representation OK :: 1.
+				// base
+				if (baseTypeName == XmlSchemaComplexType.AnyTypeName)
+					baseComplexType = XmlSchemaComplexType.AnyType;
+
+				if (baseComplexType != null && baseComplexType.ContentType != XmlSchemaContentType.TextOnly) {
+					error (h, "Base schema complex type of a simple content must be simple content type. Base type is " + baseTypeName);
+				} else if (sce == null && (baseSimpleType != null && baseTypeName.Namespace != XmlSchema.Namespace)) {
+					error (h, "If a simple content is not an extension, base schema type must be complex type. Base type is " + baseTypeName);
+				} else if (baseTypeName.Namespace == XmlSchema.Namespace) {
+					if (XmlSchemaDatatype.FromName (baseTypeName) == null)
+						error (h, "Invalid schema data type was specified: " + baseTypeName);
+					// do nothing for particle.
+				}
+				// otherwise, it might be missing sub components.
+				else if (baseType == null && !schema.missedSubComponents)// && schema.Schemas [baseTypeName.Namespace] != null)
+					error (h, "Referenced base schema type " + baseTypeName + " was not found in the corresponding schema.");
+			}
+
+			// complexType/complexContent/extension
+			if (cce != null) {
+				// ContentTypeParticle
+				if (baseComplexType == null) {
+					// Basically it is an error. Considering ValidationEventHandler.
+				}
+				else if (baseComplexType.ContentTypeParticle == XmlSchemaParticle.Empty
+					|| baseComplexType == XmlSchemaComplexType.AnyType)
+					contentTypeParticle = cce.Particle;
+				else if (cce.Particle == null || cce.Particle == XmlSchemaParticle.Empty)
+					contentTypeParticle = baseComplexType.ContentTypeParticle;
+				else {
+					// create a new sequences that merges both contents.
+					XmlSchemaSequence seq = new XmlSchemaSequence ();
+					seq.Items.Add (baseComplexType.ContentTypeParticle);
+					seq.Items.Add (cce.Particle);
+					seq.Compile (h, schema);
+					seq.Validate (h, schema);
+					contentTypeParticle = seq;
+				}
+
+				// I don't think 3.4.6 Derivation Valid (Extension) :: 1.2
+				// is constraining anything here, since 3.4.2 {attribute uses}
+				// defines as to include base type's attribute uses.
+				localAnyAttribute = cce.AnyAttribute;
+				if (baseComplexType != null) {
+					foreach (XmlSchemaAttribute attr in baseComplexType.AttributeUses)
+						XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
+					baseAnyAttribute = baseComplexType.AttributeWildcard;
+				}
+				// attributes
+				errorCount += XmlSchemaUtil.ValidateAttributesResolved (
+					this.attributeUses, h, schema, cce.Attributes, 
+					cce.AnyAttribute , ref attributeWildcard, null);
+
+				// After adding them, test extension validity.
+				if (baseComplexType != null)
+					this.ValidateComplexBaseDerivationValidExtension (baseComplexType, h, schema);
+				else if (baseSimpleType != null)
+					this.ValidateSimpleBaseDerivationValidExtension (baseSimpleType, h, schema);
+			}
+			// complexType/complexContent/restriction
+			if (ccr != null) {
+				// For ValidationEventHandler.
+				if (baseComplexType == null)
+					baseComplexType = XmlSchemaComplexType.AnyType;
+
+				// ContentTypeParticles (It must contain base type's particle).
+				if (ccr.Particle != null) {
+					ccr.Particle.Validate (h, schema);
+					contentTypeParticle = ccr.Particle;
+				}
+				else
+					contentTypeParticle = XmlSchemaParticle.Empty;
+
+				localAnyAttribute = ccr.AnyAttribute;
+				this.attributeWildcard = localAnyAttribute;
+				if (baseComplexType != null)
+					baseAnyAttribute = baseComplexType.AttributeWildcard;
+				if (baseAnyAttribute != null && localAnyAttribute != null)
+					// 1.3 attribute wildcard subset. (=> 3.10.6)
+					baseAnyAttribute.ValidateWildcardSubset (localAnyAttribute, h, schema);
+
+				// FIXME: Check 3.4.2 Complex Type Definition with complex content Schema Component
+				// and its {attribute uses} and {attribute wildcard}
+				errorCount += XmlSchemaUtil.ValidateAttributesResolved (
+					this.attributeUses, h, schema, ccr.Attributes, 
+					ccr.AnyAttribute, ref attributeWildcard, null);
+				foreach (XmlSchemaAttribute attr in baseComplexType.AttributeUses) {
+					if (attributeUses [attr.QualifiedName] == null)
+						XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
+				}
+
+				// Derivation Valid (Restriction, Complex) :: 5.
+				// Also see E1-15 of http://www.w3.org/2001/05/xmlschema-errata#Errata1
+				// 5.1 shouled be in scr (XmlSchemaSimpleContentRestriction)
+				this.ValidateDerivationValidRestriction (baseComplexType, h, schema);
+			}
+			// complexType/simpleContent/extension
+			if (sce != null) {
+				errorCount += XmlSchemaUtil.ValidateAttributesResolved (
+					this.attributeUses, h, schema, sce.Attributes, 
+					sce.AnyAttribute, ref attributeWildcard, null);
+
+				// Attributes
+				// I don't think 3.4.6 Derivation Valid (Extension) :: 1.2
+				// is constraining anything here, since 3.4.2 {attribute uses}
+				// defines as to include base type's attribute uses.
+				localAnyAttribute = sce.AnyAttribute;
+
+				if (baseComplexType != null) {
+					baseAnyAttribute = baseComplexType.AttributeWildcard;
+
+					foreach (XmlSchemaAttribute attr in baseComplexType.AttributeUses)
+						XmlSchemaUtil.AddToTable (attributeUses, attr, attr.QualifiedName, h);
+				}
+				if (baseAnyAttribute != null && localAnyAttribute != null)
+					// 1.3 attribute wildcard subset. (=> 3.10.6)
+					localAnyAttribute.ValidateWildcardSubset (baseAnyAttribute, h, schema);
+			}
+			// complexType/simpleContent/restriction
+			if (scr != null) {
+				if (baseComplexType == null) {
+					// 3.4.3 :: 2.
+					error (h, "Base type of a simple content restriction must be a complex type.");
+				} else {
+					// Attributes
+					baseAnyAttribute = baseComplexType.AttributeWildcard;
+
+					localAnyAttribute = scr.AnyAttribute;
+					if (localAnyAttribute != null && baseAnyAttribute != null)
+						// 1.3 attribute wildcard subset. (=> 3.10.6)
+						baseAnyAttribute.ValidateWildcardSubset (localAnyAttribute, h, schema);
+					// TODO: 3.4.6 :: 5.1. Beware that There is an errata for 5.1!!
+					// http://www.w3.org/2001/05/xmlschema-errata#Errata1
+
+					// FIXME: Check 3.4.2 Complex Type Definition with simple content Schema Component
+					// and its {attribute uses} and {attribute wildcard}
+					errorCount += XmlSchemaUtil.ValidateAttributesResolved (
+						this.attributeUses, h, schema, scr.Attributes, 
+						scr.AnyAttribute, ref attributeWildcard, null);
+				}
+			}
+
+			// Common process of AttributeWildcard.
+			// TODO: Check 3.4.2 {attribute wildcard} to fill the complete wildcard.
+			if (localAnyAttribute != null) {
+				this.attributeWildcard = localAnyAttribute;
+			}
+			else
+				this.attributeWildcard = baseAnyAttribute;
+			this.baseSchemaTypeInternal = baseType;
+		}
+
+		private void AddExtensionAttributes (XmlSchemaObjectCollection attributes,
+			XmlSchemaAnyAttribute anyAttribute, ValidationEventHandler h, XmlSchema schema)
+		{
+		}
+
+		// It was formerly placed directly in ContentType property.
+		// I get it out, since ContentType is _post_ compilation property value.
+		private XmlSchemaContentType GetContentType ()
+		{
+			if (this.isMixed)
+				return XmlSchemaContentType.Mixed;
+			XmlSchemaComplexContent xcc = 
+				ContentModel as XmlSchemaComplexContent;
+			if (xcc != null && xcc.IsMixed)
+				return XmlSchemaContentType.Mixed;
+
+			XmlSchemaSimpleContent xsc = ContentModel as XmlSchemaSimpleContent;
+			if (xsc != null)
+				return XmlSchemaContentType.TextOnly;
+
+			return contentTypeParticle != XmlSchemaParticle.Empty ?
+				XmlSchemaContentType.ElementOnly :
+				XmlSchemaContentType.Empty;
+		}
+
+		// 3.4.6 Type Derivation OK (Complex)
+		internal void ValidateTypeDerivationOK (object b, ValidationEventHandler h, XmlSchema schema)
+		{
+			// AnyType derives from AnyType itself.
+			if (this == XmlSchemaComplexType.AnyType && BaseSchemaType == this)
+				return;
+
+			XmlSchemaType bst = b as XmlSchemaType;
+			if (b == this)	// 1 and 2.1
+				return;
+			if (bst != null && (resolvedDerivedBy & bst.FinalResolved) != 0) // 1
+				error (h, "Derivation type " + resolvedDerivedBy + " is prohibited by the base type.");
+			if (BaseSchemaType == b) // 2.2
+				return;
+			if (BaseSchemaType == XmlSchemaComplexType.AnyType) { // 2.3.1
+				error (h, "Derived type's base schema type is anyType.");
+				return;
+			}
+			// 2.3.2.1
+			XmlSchemaComplexType dbct = BaseSchemaType as XmlSchemaComplexType;
+			if (dbct != null) {
+				dbct.ValidateTypeDerivationOK (b, h, schema);
+				return;
+			}
+			// 2.3.2.2
+			XmlSchemaSimpleType dbst = BaseSchemaType as XmlSchemaSimpleType;
+			if (dbst != null) {
+				dbst.ValidateTypeDerivationOK (b, h, schema, true);
+				return;
+			}
+		}
+
+		// Term. 1 of 3.4.6 Derivation Valid (Extension)
+		internal void ValidateComplexBaseDerivationValidExtension (XmlSchemaComplexType baseComplexType,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			// 1.1
+			if ((baseComplexType.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)
+				error (h, "Derivation by extension is prohibited.");
+			// 1.2
+			foreach (XmlSchemaAttribute ba in baseComplexType.AttributeUses) {
+				XmlSchemaAttribute da = AttributeUses [ba.QualifiedName] as XmlSchemaAttribute;
+				if (da == null)
+					error (h, "Invalid complex type derivation by extension was found. Missing attribute was found: " + ba.QualifiedName + " .");
+				// TODO: How to evaluate "equal" type ...?
+			}
+			// 1.3 -> 3.10.6 Wildcard Subset.
+			if (AnyAttribute != null) {
+				if (baseComplexType.AnyAttribute == null)
+					error (h, "Invalid complex type derivation by extension was found. Base complex type does not have an attribute wildcard.");
+				else
+					baseComplexType.AnyAttribute.ValidateWildcardSubset (AnyAttribute, h, schema);
+			}
+
+			// 1.4 => 1.4.2 (1.4.1 would be included in SimpleContentExtention).
+			// 1.4.2.1
+//			if (contentTypeParticle == null)
+//				error (h, "Extended complex type's content type must not be empty.");
+			// 1.4.2.2.1
+			if (baseComplexType.ContentType != XmlSchemaContentType.Empty) {
+				// 1.4.2.2.2.1
+				if (this.GetContentType () == baseComplexType.ContentType) {
+					// nothing to do
+				}
+				// 1.4.2.2.2.2
+				// 3.9.6 Particle Valid (Extension)
+				else if (this.contentTypeParticle != baseComplexType.ContentTypeParticle) {
+					XmlSchemaSequence seq = contentTypeParticle as XmlSchemaSequence;
+					if (contentTypeParticle.ValidatedMinOccurs != 1 ||
+						contentTypeParticle.ValidatedMaxOccurs != 1 ||
+						seq == null)
+						error (h, "Invalid complex content extension was found.");
+					else {
+						// Identical sequence item should be checked, but
+						// I think it is naturally achieved as coded above.
+					}
+
+				}
+				else
+					error (h, "Invalid complex content extension was found. Extended complex type has different content type from base type.");
+			}
+		}
+
+		// Term. 2 of 3.4.6 Derivation Valid (Extension)
+		internal void ValidateSimpleBaseDerivationValidExtension (object baseType,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			XmlSchemaSimpleType st = baseType as XmlSchemaSimpleType;
+			if (st != null && (st.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)
+				error (h, "Extension is prohibited by the base type.");
+
+			XmlSchemaDatatype dt = baseType as XmlSchemaDatatype;
+			if (dt == null)
+				dt = st.Datatype;
+			if (dt != this.Datatype)
+				error (h, "To extend simple type, a complex type must have the same content type as the base type.");
+
+			/*
+			switch (resolvedContentType) {
+			case XmlSchemaContentType.Mixed:
+			case XmlSchemaContentType.TextOnly:
+				XmlSchemaSimpleType st = baseType as XmlSchemaSimpleType;
+				if ((st == null && Datatype != baseType) ||
+					(st != null && st.Datatype != Datatype))
+					goto case XmlSchemaContentType.ElementOnly;
+				if (st != null
+					&& (st.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0)
+					error (h, "Extension is prohibited by the base type.");
+				break;
+			case XmlSchemaContentType.ElementOnly:
+			case XmlSchemaContentType.Empty:
+				error (h, "To extend simple type, a complex type must have the same content type as the base type.");
+				break;
+			}
+			*/
+		}
+
+		internal void ValidateDerivationValidRestriction (XmlSchemaComplexType baseType,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			// 1.
+			if (baseType == null) {
+				error (h, "Base schema type is not a complex type.");
+				return;
+			}
+			if ((baseType.FinalResolved & XmlSchemaDerivationMethod.Restriction) != 0) {
+				error (h, "Prohibited derivation by restriction by base schema type.");
+				return;
+			}
+			// TODO: 2. - 4.
+
+			// 5.
+			if (contentTypeParticle == XmlSchemaParticle.Empty) {
+				// TODO: 5.1
+				// 5.2
+				if (baseType.ContentTypeParticle != XmlSchemaParticle.Empty &&
+					!baseType.ContentTypeParticle.ValidateIsEmptiable ())
+				error (h, "Invalid content type derivation.");
+			} else {
+				// 5.3 => 3.9.6 Particle Valid (Restriction)
+				if (baseType.ContentTypeParticle != null) {
+					contentTypeParticle.ActualParticle.ValidateDerivationByRestriction (
+						baseType.ContentTypeParticle.ActualParticle, h, schema);
+				}
+			}
+		}
+
+#region Read
 		//<complexType
 		//  abstract = boolean : false
 		//  block = (#all | List of (extension | restriction)) 
@@ -400,13 +886,15 @@ namespace System.Xml.Schema
 				}
 				else if(reader.Name == "block")
 				{
-					ctype.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block");
+					ctype.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block",
+						XmlSchemaUtil.ComplexTypeBlockAllowed);
 					if(innerex != null)
 						warn(h,"some invalid values for block attribute were found",innerex);
 				}
 				else if(reader.Name == "final")
 				{
-					ctype.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block");
+					ctype.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "final",
+						XmlSchemaUtil.FinalAllowed);
 					if(innerex != null)
 						warn(h,"some invalid values for final attribute were found",innerex);
 				}
@@ -543,5 +1031,6 @@ namespace System.Xml.Schema
 			}
 			return ctype;
 		}
+#endregion
 	}
 }

+ 7 - 0
mcs/class/System.XML/System.Xml.Schema/XmlSchemaContent.cs

@@ -9,7 +9,14 @@ namespace System.Xml.Schema
 	/// </summary>
 	public abstract class XmlSchemaContent : XmlSchemaAnnotated
 	{
+		internal object actualBaseSchemaType;
+
 		protected XmlSchemaContent()
 		{}
+
+		internal object ActualBaseSchemaType
+		{
+			get { return actualBaseSchemaType; }
+		}
 	}
 }

+ 30 - 3
mcs/class/System.XML/System.Xml.Schema/XmlSchemaDatatype.cs

@@ -64,7 +64,6 @@ namespace System.Xml.Schema
 			}
 		}
 
-		//TODO: This should return all appropriate inbuilt type
 		internal static XmlSchemaDatatype FromName (XmlQualifiedName qname)
 		{
 			if (qname.Namespace != XmlSchema.Namespace)
@@ -72,10 +71,11 @@ namespace System.Xml.Schema
 			return FromName (qname.Name);
 		}
 
-		//TODO: This should return all appropriate inbuilt type
 		internal static XmlSchemaDatatype FromName (string localName)
 		{
 			switch (localName) {
+//			case "anyType":
+//				return datatypeAnySimpleType;
 			case "string":
 				return datatypeString;
 			case "normalizedString":
@@ -142,17 +142,36 @@ namespace System.Xml.Schema
 				return datatypeBoolean;
 			case "anyURI":
 				return datatypeAnyURI;
+			case "duration":
+				return datatypeDuration;
 			case "dateTime":
 				return datatypeDateTime;
 			case "date":
 				return datatypeDate;
 			case "time":
 				return datatypeTime;
+			case "hexBinary":
+				return datatypeHexBinary;
+			case "QName":
+				return datatypeQName;
+			case "gYearMonth":
+				return datatypeGYearMonth;
+			case "gMonthDay":
+				return datatypeGMonthDay;
+			case "gYear":
+				return datatypeGYear;
+			case "gMonth":
+				return datatypeGMonth;
+			case "gDay":
+				return datatypeGDay;
 			default:
-				throw new NotImplementedException ("Unknown type: " + localName);
+//				throw new NotImplementedException ("Unknown type: " + localName);
+				// Maybe invalid name was specified. In such cases, let processors handle them.
+				return null;
 			}
 		}
 
+//		private static XsdAnySimpleType datatypeAnySimpleType = new XsdAnySimpleType ();
 		private static XsdString datatypeString = new XsdString ();
 		private static XsdNormalizedString datatypeNormalizedString = new XsdNormalizedString ();
 		private static XsdToken datatypeToken = new XsdToken ();
@@ -186,8 +205,16 @@ namespace System.Xml.Schema
 		private static XsdBase64Binary datatypeBase64Binary = new XsdBase64Binary ();
 		private static XsdBoolean datatypeBoolean = new XsdBoolean ();
 		private static XsdAnyURI datatypeAnyURI = new XsdAnyURI ();
+		private static XsdDuration datatypeDuration = new XsdDuration ();
 		private static XsdDateTime datatypeDateTime = new XsdDateTime ();
 		private static XsdDate datatypeDate = new XsdDate ();
 		private static XsdTime datatypeTime = new XsdTime ();
+		private static XsdHexBinary datatypeHexBinary = new XsdHexBinary ();
+		private static XsdQName datatypeQName = new XsdQName ();
+		private static XsdGYearMonth datatypeGYearMonth = new XsdGYearMonth ();
+		private static XsdGMonthDay datatypeGMonthDay = new XsdGMonthDay ();
+		private static XsdGYear datatypeGYear = new XsdGYear ();
+		private static XsdGMonth datatypeGMonth = new XsdGMonth ();
+		private static XsdGDay datatypeGDay = new XsdGDay ();
 	}
 }

+ 378 - 56
mcs/class/System.XML/System.Xml.Schema/XmlSchemaElement.cs

@@ -1,6 +1,12 @@
-// Author: Dwivedi, Ajay kumar
-//            [email protected]
+//
+// System.Xml.Schema.XmlSchemaElement.cs
+//
+// Authors:
+//	Dwivedi, Ajay kumar  [email protected]
+//	Enomoto, Atsushi     [email protected]
+//
 using System;
+using System.Collections;
 using System.Xml;
 using System.Xml.Serialization;
 using System.ComponentModel;
@@ -31,7 +37,12 @@ namespace System.Xml.Schema
 		private XmlQualifiedName substitutionGroup;
 		internal bool parentIsSchema = false;
 		private string targetNamespace;
-		private string hash;
+		private string validatedDefaultValue;
+		private string validatedFixedValue;
+		internal bool actualIsAbstract;
+		internal bool actualIsNillable;
+		private ArrayList substitutingElements = new ArrayList ();
+		XmlSchemaElement referencedElement;
 
 		private static string xmlname = "element";
 
@@ -158,19 +169,66 @@ namespace System.Xml.Schema
 		[XmlIgnore]
 		public object ElementType 
 		{
-			get{ return elementType; }
+			get {
+				if (referencedElement != null)
+					return referencedElement.ElementType;
+				else
+					return elementType;
+			}
 		}
 		
 		[XmlIgnore]
 		public XmlSchemaDerivationMethod BlockResolved 
 		{
-			get{ return blockResolved; }
+			get{
+				if (referencedElement != null)
+					return referencedElement.BlockResolved;
+				else
+					return blockResolved;
+			}
 		}
 		
 		[XmlIgnore]
 		public XmlSchemaDerivationMethod FinalResolved 
 		{
-			get{ return finalResolved; }
+			get{
+				if (referencedElement != null)
+					return referencedElement.FinalResolved;
+				else
+					return finalResolved;
+			}
+		}
+
+		// Post compilation default value (normalized)
+		internal string ValidatedDefaultValue
+		{
+			get{
+				if (referencedElement != null)
+					return referencedElement.ValidatedDefaultValue;
+				else
+					return validatedDefaultValue;
+			}
+		}
+
+		// Post compilation fixed value (normalized)
+		internal string ValidatedFixedValue 
+		{
+			get{
+				if (referencedElement != null)
+					return referencedElement.ValidatedFixedValue;
+				else
+					return validatedFixedValue;
+			}
+		}
+
+		internal ArrayList SubstitutingElements
+		{
+			get {
+				if (referencedElement != null)
+					return referencedElement.SubstitutingElements;
+				else
+					return this.substitutingElements;
+			}
 		}
 
 		#endregion
@@ -201,7 +259,7 @@ namespace System.Xml.Schema
 		///		6. default and fixed must not both be present.(Actually both are absent)
 		/// </remarks>	
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
@@ -210,7 +268,7 @@ namespace System.Xml.Schema
 			if(this.defaultValue != null && this.fixedValue != null)
 				error(h,"both default and fixed can't be present");
 
-			if(parentIsSchema)
+			if(parentIsSchema || isRedefineChild)
 			{
 				if(this.refName != null && !RefName.IsEmpty)
 					error(h,"ref must be absent");
@@ -220,8 +278,8 @@ namespace System.Xml.Schema
 				else if(!XmlSchemaUtil.CheckNCName(this.name)) // b1.2
 					error(h,"attribute name must be NCName");
 				else
-					this.qName = new XmlQualifiedName(this.name, schema.TargetNamespace);
-				
+					this.qName = new XmlQualifiedName (this.name, schema.TargetNamespace);
+
 				if(form != XmlSchemaForm.None)
 					error(h,"form must be absent");
 				if(MinOccursString != null)
@@ -233,28 +291,15 @@ namespace System.Xml.Schema
 				if(final == XmlSchemaDerivationMethod.All)
 					finalResolved = allfinal;
 				else if(final == XmlSchemaDerivationMethod.None)
-					finalResolved = allfinal;
+					finalResolved = XmlSchemaDerivationMethod.Empty;
 				else 
 				{
-					if((final & ~allfinal) != 0)
+//					if((final & ~allfinal) != 0)
+					if ((final | XmlSchemaUtil.FinalAllowed) != XmlSchemaUtil.FinalAllowed)
 						warn(h,"some values for final are invalid in this context");
 					finalResolved = final & allfinal;
 				}
 
-				XmlSchemaDerivationMethod allblock = XmlSchemaDerivationMethod.Extension | 
-					XmlSchemaDerivationMethod.Restriction | XmlSchemaDerivationMethod.Substitution;
-
-				if(block == XmlSchemaDerivationMethod.All)
-					blockResolved = allblock;
-				else if(block == XmlSchemaDerivationMethod.None)
-					blockResolved = allblock;
-				else
-				{
-					if((block & ~allblock) != 0)
-						warn(h,"Some of the values for block are invalid in this context");
-					blockResolved = block & allblock;
-				}
-
 				if(schemaType != null && schemaTypeName != null && !schemaTypeName.IsEmpty)
 				{
 					error(h,"both schemaType and content can't be present");
@@ -301,19 +346,18 @@ namespace System.Xml.Schema
 					error(h,"substitutionGroup must be absent");
 				if(final != XmlSchemaDerivationMethod.None)
 					error(h,"final must be absent");
-				if(isAbstract)
-					error(h,"abstract must be absent");
+				// This is not W3C REC 3.3.3 requirement
+//				if(isAbstract)
+//					error(h,"abstract must be absent");
 
-				//FIXME: Should we reset the values
-				if(MinOccurs > MaxOccurs)
-					error(h,"minOccurs must be less than or equal to maxOccurs");
+				CompileOccurence (h, schema);
 
 				if(refName == null || RefName.IsEmpty)
 				{
 					if(form == XmlSchemaForm.Qualified || (form == XmlSchemaForm.None && schema.ElementFormDefault == XmlSchemaForm.Qualified))
 						this.targetNamespace = schema.TargetNamespace;
 					else
-						this.targetNamespace = string.Empty;
+						this.targetNamespace = "";
 
 					if(this.name == null)	//b1
 						error(h,"Required attribute name must be present");
@@ -322,19 +366,21 @@ namespace System.Xml.Schema
 					else
 						this.qName = new XmlQualifiedName(this.name, this.targetNamespace);
 				
+					/*
 					XmlSchemaDerivationMethod allblock = XmlSchemaDerivationMethod.Extension | 
 						XmlSchemaDerivationMethod.Restriction | XmlSchemaDerivationMethod.Substitution;
 
 					if(block == XmlSchemaDerivationMethod.All)
 						blockResolved = allblock;
-					else if(block == XmlSchemaDerivationMethod.None)
-						blockResolved = allblock;
+//					else if(block == XmlSchemaDerivationMethod.None)
+//						blockResolved = allblock;
 					else
 					{
 						if((block & ~allblock) != 0)
 							warn(h,"Some of the values for block are invalid in this context");
 						blockResolved = block & allblock;
 					}
+					*/
 
 					if(schemaType != null && schemaTypeName != null && !schemaTypeName.IsEmpty)
 					{
@@ -401,42 +447,316 @@ namespace System.Xml.Schema
 						error(h,"simpleType or complexType must be absent");
 
 					qName = RefName;
-					schema.MissingElementTypeRefs.Add (this);
 				}
 			}
 
-			// PSVI contribution for XmlSchemaElement
-			if(refName == null || RefName.IsEmpty) {
-				if (this.schemaType != null)
-					this.elementType = schemaType;
-				else {
-					XmlSchemaType xsType = null;
-					if (schemaTypeName.Namespace == XmlSchema.Namespace)
-						this.elementType = XmlSchemaDatatype.FromName (schemaTypeName);
-					else if (schemaTypeName == XmlQualifiedName.Empty)
-						elementType = XmlSchemaComplexType.AnyType;
-					else
-						schema.MissingElementTypeRefs.Add (this);
+			switch (block) {
+			case XmlSchemaDerivationMethod.All:
+				blockResolved = XmlSchemaDerivationMethod.All;
+				break;
+			case XmlSchemaDerivationMethod.None:
+				blockResolved = XmlSchemaDerivationMethod.Empty;
+				break;
+			default:
+				if ((block | XmlSchemaUtil.ElementBlockAllowed) != XmlSchemaUtil.ElementBlockAllowed)
+					warn(h,"Some of the values for block are invalid in this context");
+				blockResolved = block;
+				break;
+			}
+
+			if (Constraints != null) {
+				XmlSchemaObjectTable table = new XmlSchemaObjectTable ();
+				foreach (XmlSchemaIdentityConstraint c in Constraints) {
+					XmlSchemaUtil.AddToTable (table, c, c.QualifiedName, h);
 				}
 			}
-		
+
 			XmlSchemaUtil.CompileID(Id,this,schema.IDCollection,h);
 
 			this.CompilationId = schema.CompilationId;
 			return errorCount;
 		}
 
-		internal void SetSchemaType (object type)
-		{
-			this.elementType = type;
-		}
-		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
+			if (IsValidated (schema.CompilationId))
+				return errorCount;
+
+			// See XML Schema Structures 3.6 for the complete description.
+
+			// Element Declaration Properties Correct
+			// 1. = 3.3.1 (modulo 5.3)
+
+			// 3.3.1:
+			// {annotation} is as is.
+			// {name}, {target namespace}, {scope}, {disallowed substitution},
+			// {substitution group exclusions} (handled the same as 'disallowed substitution')
+			// and {identity-constraint-definitions} are Compile()d.
+			// {value constraint} is going to be filled in step 2.
+
+			// actual {nillable}, {abstract} 
+			this.actualIsNillable = IsNillable;
+			this.actualIsAbstract = IsAbstract;
+
+			// {type} from here
+			XmlSchemaDatatype datatype = null;
+			if (schemaType != null)
+				elementType = schemaType;
+			else if (SchemaTypeName != XmlQualifiedName.Empty) {
+				XmlSchemaType type = schema.SchemaTypes [SchemaTypeName] as XmlSchemaType;
+				// If el is null, then it is missing sub components .
+				if (type != null) {
+					type.Validate (h, schema);
+					elementType = type;
+				}
+				else if (SchemaTypeName == XmlSchemaComplexType.AnyTypeName)
+					elementType = XmlSchemaComplexType.AnyType;
+				else if (SchemaTypeName.Namespace == XmlSchema.Namespace) {
+					datatype = XmlSchemaDatatype.FromName (SchemaTypeName);
+					if (datatype == null)
+						error (h, "Invalid schema datatype was specified.");
+					else
+						elementType = datatype;
+				}
+				// otherwise, it might be missing sub components.
+				else if (!schema.missedSubComponents)
+					error (h, "Referenced element schema type " + SchemaTypeName + " was not found in the corresponding schema.");
+			}
+			else if (RefName != XmlQualifiedName.Empty)
+			{
+				XmlSchemaElement refElem = schema.Elements [RefName] as XmlSchemaElement;
+				// If el is null, then it is missing sub components .
+				if (refElem != null) {
+					this.referencedElement = refElem;
+					errorCount += refElem.Validate (h, schema);
+					elementType = refElem.ElementType;
+					this.validatedDefaultValue = refElem.validatedDefaultValue;
+					this.validatedFixedValue = refElem.validatedFixedValue;
+					this.actualIsAbstract = refElem.IsAbstract;
+					this.actualIsNillable = refElem.IsNillable;
+				}
+				// otherwise, it might be missing sub components.
+				else if (!schema.missedSubComponents)// && schema.Schemas [RefName.Namespace] != null)
+					error (h, "Referenced element " + RefName + " was not found in the corresponding schema.");
+			}
+			
+			// Otherwise the -ur type- definition.
+			if (elementType == null)
+				elementType = XmlSchemaComplexType.AnyType;
+
+			XmlSchemaType xsType = elementType as XmlSchemaType;
+			if (xsType != null) {
+				errorCount += xsType.Validate (h, schema);
+				datatype = xsType.Datatype;
+			}
+			// basic {type} is now filled, except for derivation by {substitution group}.
+
+			// {substitution group affiliation}
+			// 3. subsitution group's type derivation check.
+			if (this.SubstitutionGroup != XmlQualifiedName.Empty) {
+				XmlSchemaElement substElem = schema.Elements [SubstitutionGroup] as XmlSchemaElement;
+				// If el is null, then it is missing sub components .
+				if (substElem != null) {
+					substElem.Validate (h, schema);
+					XmlSchemaType substSchemaType = substElem.ElementType as XmlSchemaType;
+					if (substSchemaType != null) {
+						// 3.3.6 Properties Correct 3.
+						if ((substElem.FinalResolved & XmlSchemaDerivationMethod.Substitution) != 0)
+							error (h, "Substituted element blocks substitution.");
+						if (xsType != null && (substElem.FinalResolved & xsType.DerivedBy) != 0)
+							error (h, "Invalid derivation was found. Substituted element prohibits this derivation method: " + xsType.DerivedBy + ".");
+					}
+					XmlSchemaComplexType xsComplexType = xsType as XmlSchemaComplexType;
+					if (xsComplexType != null)
+						xsComplexType.ValidateTypeDerivationOK (substElem.ElementType, h, schema);
+					else {
+						XmlSchemaSimpleType xsSimpleType = xsType as XmlSchemaSimpleType;
+						if (xsSimpleType != null)
+							xsSimpleType.ValidateTypeDerivationOK (substElem.ElementType, h, schema, true);
+					}
+					substElem.substitutingElements.Add (this);
+				}
+				// otherwise, it might be missing sub components.
+				else if (!schema.missedSubComponents)
+					error (h, "Referenced element type " + SubstitutionGroup + " was not found in the corresponding schema.");
+			}
+
+			// 2. ElementDefaultValid
+			// 4. ID with {value constraint} is prohibited.
+			if (defaultValue != null || fixedValue != null) {
+				ValidateElementDefaultValidImmediate (h, schema);
+				if (datatype != null && // Such situation is basically an error. For ValidationEventHandler.
+					datatype.TokenizedType == XmlTokenizedType.ID)
+					error (h, "Element type is ID, which does not allows default or fixed values.");
+			}
+
+			// Identity constraints (3.11.3 / 3.11.6)
+			foreach (XmlSchemaIdentityConstraint ident in Constraints)
+				ident.Validate (h, schema);
+
+			ValidationId = schema.ValidationId;
 			return errorCount;
 		}
 
+		internal override void ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			XmlSchemaElement baseElement = baseParticle as XmlSchemaElement;
+			if (baseElement != null) {
+				ValidateDerivationByRestrictionNameAndTypeOK (baseElement, h, schema);
+				return;
+			}
+
+			XmlSchemaAny baseAny = baseParticle as XmlSchemaAny;
+			if (baseAny != null) {
+				// NSCompat
+				baseAny.ValidateWildcardAllowsNamespaceName (this.QualifiedName.Namespace, h, schema, true);
+				ValidateOccurenceRangeOK (baseAny, h, schema);
+				return;
+			}
+		}
+
+		private void ValidateDerivationByRestrictionNameAndTypeOK (XmlSchemaElement baseElement,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			// 1.
+			if (this.QualifiedName != baseElement.QualifiedName)
+				error (h, "Invalid derivation by restriction of particle was found. Both elements must have the same name.");
+			// 2.
+			if (this.isNillable && !baseElement.isNillable)
+				error (h, "Invalid element derivation by restriction of particle was found. Base element is not nillable and derived type is nillable.");
+			// 3.
+			ValidateOccurenceRangeOK (baseElement, h, schema);
+			// 4.
+			if (baseElement.ValidatedFixedValue != null &&
+				baseElement.ValidatedFixedValue != this.ValidatedFixedValue)
+				error (h, "Invalid element derivation by restriction of particle was found. Both fixed value must be the same.");
+			// 5. TODO: What is "identity constraints subset" ???
+
+			// 6. 
+			if ((baseElement.BlockResolved | this.BlockResolved) != this.BlockResolved)
+				error (h, "Invalid derivation by restriction of particle was found. Derived element must contain all of the base element's block value.");
+			// 7.
+			if (baseElement.ElementType != null) {
+				XmlSchemaComplexType derivedCType = this.ElementType as XmlSchemaComplexType;
+				if (derivedCType != null)
+					// W3C REC says that it is Type Derivation OK to be check, but
+					// in fact it should be DerivationValid (Restriction, Complex).
+					derivedCType.ValidateDerivationValidRestriction (
+						baseElement.ElementType as XmlSchemaComplexType, h, schema);
+					// derivedCType.ValidateTypeDerivationOK (baseElement.ElementType, h, schema);
+				else {
+					XmlSchemaSimpleType derivedSType = this.ElementType as XmlSchemaSimpleType;
+					if (derivedSType != null)
+						derivedSType.ValidateTypeDerivationOK (baseElement.ElementType, h, schema, true);
+					else if (baseElement.ElementType != this.ElementType)
+						error (h, "Invalid element derivation by restriction of particle was found. Both primitive types differ.");
+				}
+			}
+		}
+
+		internal override void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema)
+		{
+			XmlSchemaComplexType ct = this.ElementType as XmlSchemaComplexType;
+			if (ct == null || ct.ContentTypeParticle == null)
+				return;
+			ct.ContentTypeParticle.CheckRecursion (depth + 1, h, schema);
+		}
+
+		internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames, ArrayList nsNames,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			if (qnames.Contains (this.QualifiedName))
+				error (h, "Ambiguous element label was detected: " + this.QualifiedName);
+			else {
+				foreach (XmlSchemaAny any in nsNames) {
+					if (any.ValidatedMaxOccurs == 0)
+						continue;
+					if (any.HasValueAny ||
+						any.HasValueLocal && this.QualifiedName.Namespace == "" ||
+						any.HasValueOther && this.QualifiedName.Namespace != this.targetNamespace ||
+						any.HasValueTargetNamespace && this.QualifiedName.Namespace == this.targetNamespace) {
+						error (h, "Ambiguous element label which is contained by -any- particle was detected: " + this.QualifiedName);
+						break;
+					} else {
+						bool bad = false;
+						foreach (string ns in any.ResolvedNamespaces) {
+							if (ns == this.QualifiedName.Namespace) {
+								bad = true;
+								break;
+							}
+						}
+						if (bad) {
+							error (h, "Ambiguous element label which is contained by -any- particle was detected: " + this.QualifiedName);
+							break;
+						}
+					}
+				}
+				qnames.Add (this.QualifiedName, this);
+			}
+		}
+
+		internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			XmlSchemaElement labeled = labels [this.QualifiedName] as XmlSchemaElement;
+			if (labeled == null)
+				labels.Add (this.QualifiedName, this);
+			else if (labeled.ElementType != this.ElementType)
+				error (h, "Different types are specified on the same named elements in the same sequence. Element name is " + QualifiedName);
+		}
+
+
+		// 3.3.6 Element Default Valid (Immediate)
+		private void ValidateElementDefaultValidImmediate (ValidationEventHandler h, XmlSchema schema)
+		{
+			// This presumes that ElementType is already filled.
+
+			XmlSchemaDatatype datatype = elementType as XmlSchemaDatatype;
+			XmlSchemaSimpleType simpleType = elementType as XmlSchemaSimpleType;
+			if (simpleType != null)
+				datatype = simpleType.Datatype;
+
+			if (datatype == null) {
+				XmlSchemaComplexType complexType = elementType as XmlSchemaComplexType;
+				switch (complexType.ContentType) {
+				case XmlSchemaContentType.Empty:
+				case XmlSchemaContentType.ElementOnly:
+					error (h, "Element content type must be simple type or mixed.");
+					break;
+				}
+				datatype = XmlSchemaSimpleType.AnySimpleType;
+			}
+
+			XmlNamespaceManager nsmgr = null;
+			if (datatype.TokenizedType == XmlTokenizedType.QName) {
+				if (this.Namespaces != null)
+					foreach (XmlQualifiedName qname in Namespaces.ToArray ())
+						nsmgr.AddNamespace (qname.Name, qname.Namespace);
+			}
+
+			try {
+				if (defaultValue != null) {
+					validatedDefaultValue = datatype.Normalize (defaultValue);
+					datatype.ParseValue (validatedDefaultValue, null, nsmgr);
+				}
+			} catch (Exception ex) {
+				// FIXME: This is not a good way to handle exception, but
+				// I think there is no remedy for such Framework specification.
+				error (h, "The Element's default value is invalid with respect to its type definition.", ex);
+			}
+			try {
+				if (fixedValue != null) {
+					validatedFixedValue = datatype.Normalize (fixedValue);
+					datatype.ParseValue (validatedFixedValue, null, nsmgr);
+				}
+			} catch (Exception ex) {
+				// FIXME: This is not a good way to handle exception.
+				error (h, "The Element's fixed value is invalid with its type definition.", ex);
+			}
+		}
+
 		//<element
 		//  abstract = boolean : false
 		//  block = (#all | List of (extension | restriction | substitution)) 
@@ -483,7 +803,8 @@ namespace System.Xml.Schema
 				}
 				else if(reader.Name == "block")
 				{
-					element.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block");
+					element.block = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block",
+						XmlSchemaUtil.ElementBlockAllowed);
 					if(innerex != null)
 						warn(h,"some invalid values for block attribute were found",innerex);
 				}
@@ -493,7 +814,8 @@ namespace System.Xml.Schema
 				}
 				else if(reader.Name == "final")
 				{
-					element.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "block");
+					element.Final = XmlSchemaUtil.ReadDerivationAttribute(reader,out innerex, "final",
+						XmlSchemaUtil.FinalAllowed);
 					if(innerex != null)
 						warn(h,"some invalid values for final attribute were found",innerex);
 				}

+ 27 - 7
mcs/class/System.XML/System.Xml.Schema/XmlSchemaException.cs

@@ -13,6 +13,7 @@ namespace System.Xml.Schema
 	public class XmlSchemaException : System.SystemException
 	{
 		//fields
+		private bool hasLineInfo;
 		private int lineNumber;
 		private int linePosition;
 		private XmlSchemaObject sourceObj;
@@ -21,26 +22,42 @@ namespace System.Xml.Schema
 		protected XmlSchemaException(SerializationInfo info, StreamingContext context)
 			: base (info, context)
 		{
+			hasLineInfo = true;
 			this.lineNumber = info.GetInt32 ("lineNumber");
 			this.linePosition = info.GetInt32 ("linePosition");
 			this.sourceUri = info.GetString ("sourceUri");
 			this.sourceObj = info.GetValue ("sourceObj", typeof (XmlSchemaObject)) as XmlSchemaObject;
 		}
 		
-		
 		internal XmlSchemaException(string message, int lineNumber, int linePosition,
 			XmlSchemaObject sourceObject, string sourceUri, Exception innerException)
 			: base(message, innerException)
 		{
+			hasLineInfo = true;
 			this.lineNumber		= lineNumber;
 			this.linePosition	= linePosition;
 			this.sourceObj		= sourceObject;
 			this.sourceUri		= sourceUri;
 		}
+
+		internal XmlSchemaException(string message, object sender,
+			string sourceUri, XmlSchemaObject sourceObject, Exception innerException)
+			: base(message, innerException)
+		{
+			IXmlLineInfo li = sender as IXmlLineInfo;
+			if (li != null && li.HasLineInfo ()) {
+				hasLineInfo = true;
+				this.lineNumber = li.LineNumber;
+				this.linePosition = li.LinePosition;
+			}
+			this.sourceObj = sourceObject;
+		}
+
 		internal XmlSchemaException(string message, XmlSchemaObject sourceObject,
 			Exception innerException)
 			: base(message, innerException)
 		{
+			hasLineInfo = true;
 			this.lineNumber = sourceObject.LineNumber;
 			this.linePosition = sourceObject.LinePosition;
 			this.sourceObj	=	sourceObject;
@@ -71,12 +88,15 @@ namespace System.Xml.Schema
 		public override string Message
 		{
 			get {
-				string msg = base.Message;
-				if (sourceUri != null)
-					msg = String.Format ("XmlSchema error: {0}\n" +
-							     "URI: {1}, line {2}, position {3}",
-							     msg, sourceUri, lineNumber, linePosition);
-
+				string msg = "XmlSchema error: " + base.Message;
+				if (hasLineInfo)
+					msg += String.Format (" XML {0} Line {1}, Position {2}.",
+						(sourceUri != null && sourceUri != "") ? "URI: " + sourceUri + " ." : "",
+						lineNumber,
+						linePosition);
+				if (sourceObj != null)
+					msg += String.Format (" Related schema item SourceUri: {0}, Line {1}, Position {2}.",
+						sourceObj.SourceUri, sourceObj.LineNumber, sourceObj.LinePosition);
 				return msg;
 			}
 		}

+ 39 - 4
mcs/class/System.XML/System.Xml.Schema/XmlSchemaGroup.cs

@@ -1,6 +1,12 @@
-// Author: Dwivedi, Ajay kumar
-//            [email protected]
+//
+// System.Xml.Schema.XmlSchemaGroup.cs
+//
+// Author:
+//	Dwivedi, Ajay kumar  [email protected]
+//	Atsushi Enomoto  [email protected]
+//
 using System;
+using System.Collections;
 using System.Xml.Serialization;
 using System.Xml;
 
@@ -14,6 +20,7 @@ namespace System.Xml.Schema
 		private string name;
 		private XmlSchemaGroupBase particle;
 		private XmlQualifiedName qualifiedName;
+		private bool isCircularDefinition;
 		
 		private static string xmlname = "group";
 
@@ -43,10 +50,15 @@ namespace System.Xml.Schema
 			get{ return qualifiedName;}
 		}
 
+		internal bool IsCircularDefinition
+		{
+			get { return isCircularDefinition; }
+		}
+
 		// 1. name must be present
 		// 2. MinOccurs & MaxOccurs of the Particle must be absent
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
@@ -95,8 +107,31 @@ namespace System.Xml.Schema
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
+			if (this.IsValidated (schema.ValidationId))
+				return errorCount;
+
+			// 3.8.6 Model Group Correct :: 2. Circular group disallowed.
+			if (Particle != null) {	// in case of invalid schema.
+				Particle.parentIsGroupDefinition = true;
+
+				try {
+					Particle.CheckRecursion (0, h, schema);
+				} catch (XmlSchemaException ex) {
+					error (h, ex.Message, ex);
+					this.isCircularDefinition = true;
+					return errorCount;
+				}
+				errorCount += Particle.Validate (h,schema);
+
+				Particle.ValidateUniqueParticleAttribution (new XmlSchemaObjectTable (),
+					new ArrayList (), h, schema);
+				Particle.ValidateUniqueTypeAttribution (
+					new XmlSchemaObjectTable (), h, schema);
+			}
+
+			this.ValidationId = schema.ValidationId;
 			return errorCount;
 		}
 

+ 8 - 0
mcs/class/System.XML/System.Xml.Schema/XmlSchemaGroupBase.cs

@@ -16,5 +16,13 @@ namespace System.Xml.Schema
 
 		[XmlIgnore]
 		public abstract XmlSchemaObjectCollection Items { get; }
+
+		internal void ValidateNSRecurseCheckCardinality (XmlSchemaAny any,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			foreach (XmlSchemaParticle p in Items)
+				p.ValidateDerivationByRestriction (any, h, schema);
+			ValidateOccurenceRangeOK (any, h, schema);
+		}
 	}
 }

+ 86 - 9
mcs/class/System.XML/System.Xml.Schema/XmlSchemaGroupRef.cs

@@ -1,6 +1,12 @@
-// Author: Dwivedi, Ajay kumar
-//            [email protected]
+//
+// System.Xml.Schema.XmlSchemaGroupBase.cs
+//
+// Author:
+//	Dwivedi, Ajay kumar  [email protected]
+//	Atsushi Enomoto  [email protected]
+//
 using System;
+using System.Collections;
 using System.Xml;
 using System.Xml.Serialization;
 
@@ -13,7 +19,9 @@ namespace System.Xml.Schema
 	{
 		private XmlSchemaGroupBase particle;
 		private XmlQualifiedName refName;
+		private XmlQualifiedName resolvedRefName;
 		private static string xmlname = "group";
+		private XmlSchemaGroup referencedGroup;
 
 		public XmlSchemaGroupRef()
 		{
@@ -28,23 +36,45 @@ namespace System.Xml.Schema
 		[XmlIgnore]
 		public XmlSchemaGroupBase Particle 
 		{
-			get{ return particle; }
+			get{
+				if (TargetGroup != null)
+					return TargetGroup.Particle;
+				else
+					return null;
+			}
+		}
+		internal XmlSchemaGroup TargetGroup
+		{
+			get {
+				if (referencedGroup != null && referencedGroup.IsCircularDefinition)
+					return null;
+				else
+					return referencedGroup;
+			}
 		}
+		internal override XmlSchemaParticle ActualParticle
+		{
+			get {
+				if (TargetGroup != null)
+					return TargetGroup.Particle.ActualParticle;
+				else
+					// For ValidationEventHandler and missing sub components.
+					return XmlSchemaParticle.Empty;
+			}
+		}
+
 		/// <remarks>
 		/// 1. RefName must be present
 		/// </remarks>
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
 				return 0;
 
-			//FIXME: Should we reset the values
-			if(MinOccurs > MaxOccurs)
-				error(h,"minOccurs must be less than or equal to maxOccurs");
-
 			XmlSchemaUtil.CompileID(Id,this,schema.IDCollection,h);
+			CompileOccurence (h, schema);
 
 			if(refName == null || refName.IsEmpty)
 			{
@@ -58,11 +88,58 @@ namespace System.Xml.Schema
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
+			if (IsValidated (schema.ValidationId))
+				return errorCount;
+
+			referencedGroup = schema.Groups [RefName] as XmlSchemaGroup;
+			// it might be missing sub components.
+			if (referencedGroup == null && !schema.missedSubComponents)// && schema.Schemas [RefName.Namespace] != null)
+				error (h, "Referenced group " + RefName + " was not found in the corresponding schema.");
+			else if (TargetGroup != null)
+				TargetGroup.Validate (h, schema);
+
+			ValidationId = schema.ValidationId;
 			return errorCount;
 		}
 
+		internal override void ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			if (TargetGroup != null)
+				TargetGroup.Particle.ValidateDerivationByRestriction (baseParticle, h, schema);
+		}
+
+
+		internal override void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema)
+		{
+			if (TargetGroup == null)
+				return;
+
+			if (this.recursionDepth == -1) {
+				recursionDepth = depth;
+				TargetGroup.Particle.CheckRecursion (depth, h, schema);
+				recursionDepth = -2;
+			} else if (depth == recursionDepth)
+				throw new XmlSchemaException ("Circular group reference was found.", this, null);
+		}
+
+		internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames, ArrayList nsNames,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			if (TargetGroup != null)
+				TargetGroup.Particle.ValidateUniqueParticleAttribution (qnames, nsNames, h, schema);
+		}
+
+		internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			if (TargetGroup != null)
+				TargetGroup.Particle.ValidateUniqueTypeAttribution (labels, h, schema);
+		}
+
+
 		//	<group 
 		//		 id = ID 
 		//		 ref = QName

+ 28 - 6
mcs/class/System.XML/System.Xml.Schema/XmlSchemaIdentityConstraint.cs

@@ -1,8 +1,10 @@
 // Author: Dwivedi, Ajay kumar
 //            [email protected]
 using System;
+using System.Collections;
 using System.Xml;
 using System.Xml.Serialization;
+using Mono.Xml.Schema;
 
 namespace System.Xml.Schema
 {
@@ -16,6 +18,9 @@ namespace System.Xml.Schema
 		private XmlQualifiedName qName;
 		private XmlSchemaXPath selector;
 
+		private XsdIdentitySelector compiledSelector;
+//		ArrayList compiledFields;
+
 		public XmlSchemaIdentityConstraint()
 		{
 			fields = new XmlSchemaObjectCollection();
@@ -47,12 +52,17 @@ namespace System.Xml.Schema
 		{
 			get{ return  qName; }
 		}
+
+		internal XsdIdentitySelector CompiledSelector {
+			get { return compiledSelector; }
+		}
+
 		/// <remarks>
 		/// 1. name must be present
 		/// 2. selector and field must be present
 		/// </remarks>
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
@@ -62,29 +72,41 @@ namespace System.Xml.Schema
 				error(h,"Required attribute name must be present");
 			else if(!XmlSchemaUtil.CheckNCName(this.name)) 
 				error(h,"attribute name must be NCName");
-			else
+			else {
 				this.qName = new XmlQualifiedName(Name,schema.TargetNamespace);
+				if (schema.NamedIdentities.Contains (qName))
+					error(h,"There is already same named identity constraint in this namespace.");
+				else
+					schema.NamedIdentities.Add (qName, this);
+			}
 
 			if(Selector == null)
 				error(h,"selector must be present");
 			else
 			{
+				Selector.isSelector = true;
 				errorCount += Selector.Compile(h,schema);
+				if (selector.errorCount == 0)
+					compiledSelector = new XsdIdentitySelector (Selector);
 			}
+			if (errorCount > 0)
+				return errorCount; // fatal
 
 			if(Fields.Count == 0)
 				error(h,"atleast one field value must be present");
 			else
 			{
-				foreach(XmlSchemaObject obj in Fields)
+				for (int i = 0; i < Fields.Count; i++)
 				{
-					if(obj is XmlSchemaXPath)
+					XmlSchemaXPath field = Fields [i] as XmlSchemaXPath;
+					if(field != null)
 					{
-						XmlSchemaXPath field = (XmlSchemaXPath)obj;
 						errorCount += field.Compile(h,schema);
+						if (field.errorCount == 0)
+							this.compiledSelector.AddField (new XsdIdentityField (field, i));
 					}
 					else
-						error(h,"Object of type "+obj.GetType()+" is invalid in the Fields Collection");
+						error (h, "Object of type " + Fields [i].GetType() + " is invalid in the Fields Collection");
 				}
 			}
 			XmlSchemaUtil.CompileID(Id,this,schema.IDCollection,h);

+ 3 - 11
mcs/class/System.XML/System.Xml.Schema/XmlSchemaKey.cs

@@ -20,26 +20,18 @@ namespace System.Xml.Schema
 		/// 2. selector and field must be present
 		/// </remarks>
 		[MonoTODO]
-		internal new int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
-			// If this is already compiled this time, simply skip.
-			if (this.IsComplied (schema.CompilationId))
-				return 0;
-
 			return base.Compile(h, schema);
 		}
 		
-		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
-		{
-			return errorCount;
-		}
-
+		/*
 		internal new void error(ValidationEventHandler handle, string message)
 		{
 			errorCount++;
 			ValidationHandler.RaiseValidationError(handle, this, message);
 		}
+		*/
 
 		//<key 
 		//  id = ID 

+ 22 - 6
mcs/class/System.XML/System.Xml.Schema/XmlSchemaKeyref.cs

@@ -13,6 +13,7 @@ namespace System.Xml.Schema
 	{
 		private XmlQualifiedName refer;
 		private static string xmlname = "keyref";
+		private XmlSchemaIdentityConstraint target;
 
 		public XmlSchemaKeyref()
 		{
@@ -25,19 +26,22 @@ namespace System.Xml.Schema
 			get{ return  refer; } 
 			set{ refer = value; }
 		}
+
+		internal XmlSchemaIdentityConstraint Target
+		{
+			get { return target; }
+		}
+
 		/// <remarks>
 		/// 1. name must be present
 		/// 2. selector and field must be present
 		/// 3. refer must be present
 		/// </remarks>
 		[MonoTODO]
-		internal new int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
-			// If this is already compiled this time, simply skip.
-			if (this.IsComplied (schema.CompilationId))
-				return 0;
+			base.Compile(h, schema);
 
-			errorCount += base.Compile(h, schema);
 			if(refer == null || refer.IsEmpty)
 				error(h,"refer must be present");
 			else if(!XmlSchemaUtil.CheckQName(refer))
@@ -47,16 +51,28 @@ namespace System.Xml.Schema
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate (ValidationEventHandler h, XmlSchema schema)
 		{
+			// Find target key
+			XmlSchemaIdentityConstraint target = schema.NamedIdentities [this.Refer] as XmlSchemaIdentityConstraint;
+			if (target == null)
+				error (h, "Target key was not found.");
+			else if (target is XmlSchemaKeyref)
+				error (h, "Target identity constraint was keyref.");
+			else if (target.Fields.Count != this.Fields.Count)
+				error (h, "Target identity constraint has different number of fields.");
+			else
+				this.target = target;
 			return errorCount;
 		}
 
+		/*
 		internal new void error(ValidationEventHandler handle, string message)
 		{
 			errorCount++;
 			ValidationHandler.RaiseValidationError(handle, this, message);
 		}
+		*/
 		//<key 
 		//  id = ID 
 		//  name = NCName 

+ 2 - 2
mcs/class/System.XML/System.Xml.Schema/XmlSchemaNotation.cs

@@ -48,7 +48,7 @@ namespace System.Xml.Schema
 		// 1. name and public must be present
 		// public and system must be anyURI
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
@@ -75,7 +75,7 @@ namespace System.Xml.Schema
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
 			return errorCount;
 		}

+ 62 - 9
mcs/class/System.XML/System.Xml.Schema/XmlSchemaObject.cs

@@ -1,5 +1,10 @@
-// Author: Dwivedi, Ajay kumar
-//            [email protected]
+//
+// System.Xml.Schema.XmlSchemaObject.cs
+//
+// Authors:
+//	Dwivedi, Ajay kumar  [email protected]
+//	Enomoto, Atsushi     [email protected]
+//
 using System;
 using System.Collections;
 using System.Xml.Serialization;
@@ -20,6 +25,12 @@ namespace System.Xml.Schema
 		internal bool isCompiled = false;
 		internal int errorCount = 0;
 		internal Guid CompilationId;
+		internal Guid ValidationId;
+		internal bool isRedefineChild;
+		internal bool isRedefinedComponent;
+		internal XmlSchemaObject redefinedObject;
+
+		internal bool AttributeGroupRecursionCheck;
 
 		protected XmlSchemaObject()
 		{
@@ -58,25 +69,67 @@ namespace System.Xml.Schema
 		internal void error(ValidationEventHandler handle,string message)
 		{
 			errorCount++;
-			ValidationHandler.RaiseValidationError(handle,this,message);
+			error (handle, message, null, this, null);
 		}
 		internal void warn(ValidationEventHandler handle,string message)
 		{
-			errorCount++;
-			ValidationHandler.RaiseValidationWarning(handle,this,message);
+			warn (handle, message, null, this, null);
 		}
 		internal static void error(ValidationEventHandler handle, string message, Exception innerException)
 		{
-			ValidationHandler.RaiseValidationError(handle,message, innerException);
+			error (handle, message, innerException, null, null);
 		}
 		internal static void warn(ValidationEventHandler handle, string message, Exception innerException)
 		{
-			ValidationHandler.RaiseValidationWarning(handle,message, innerException);
+			warn (handle, message, innerException, null, null);
+		}
+		internal static void error(ValidationEventHandler handle,
+			string message,
+			Exception innerException,
+			XmlSchemaObject xsobj,
+			object sender)
+		{
+			ValidationHandler.RaiseValidationEvent (handle,
+				innerException,
+				message,
+				xsobj,
+				sender,
+				null,
+				XmlSeverityType.Warning);
+		}
+		internal static void warn(ValidationEventHandler handle,
+			string message,
+			Exception innerException,
+			XmlSchemaObject xsobj,
+			object sender)
+		{
+			ValidationHandler.RaiseValidationEvent (handle,
+				innerException,
+				message,
+				xsobj,
+				sender,
+				null,
+				XmlSeverityType.Warning);
+		}
+
+		internal virtual int Compile (ValidationEventHandler h, XmlSchema schema)
+		{
+			return 0;
+		}
+
+		internal bool IsComplied (Guid compilationId)
+		{
+			return this.CompilationId == compilationId;
+		}
+
+		internal virtual int Validate (ValidationEventHandler h, XmlSchema schema)
+		{
+			return 0;
 		}
 
-		internal bool IsComplied (Guid CompilationId)
+		internal bool IsValidated (Guid validationId)
 		{
-			return this.CompilationId == CompilationId;
+			return this.ValidationId == validationId;
 		}
 	}
 }

+ 10 - 1
mcs/class/System.XML/System.Xml.Schema/XmlSchemaObjectTable.cs

@@ -45,7 +45,16 @@ namespace System.Xml.Schema
 
 		internal void Add(XmlQualifiedName name, XmlSchemaObject value)
 		{
-			table.Add(name,value);
+			if (table.ContainsKey (name))
+				throw new XmlSchemaException (
+					"Schema object for the name " + name + " already exists in this table.",
+					0, 0, value, null, null);
+			table [name] = value;
+		}
+
+		internal void Clear ()
+		{
+			table.Clear ();
 		}
 
 		internal void Set(XmlQualifiedName name, XmlSchemaObject value)

+ 120 - 2
mcs/class/System.XML/System.Xml.Schema/XmlSchemaParticle.cs

@@ -1,6 +1,7 @@
 // Author: Dwivedi, Ajay kumar
 //            [email protected]
 using System;
+using System.Collections;
 using System.Xml.Serialization;
 
 namespace System.Xml.Schema
@@ -13,6 +14,10 @@ namespace System.Xml.Schema
 		decimal minOccurs, maxOccurs;
 		string  minstr, maxstr;
 		static XmlSchemaParticle empty;
+		decimal validatedMinOccurs, validatedMaxOccurs;
+		internal int recursionDepth = -1;
+		private decimal minEffectiveTotalRange = -1;
+		internal bool parentIsGroupDefinition;
 
 		internal static XmlSchemaParticle Empty {
 			get {
@@ -37,6 +42,12 @@ namespace System.Xml.Schema
 			get{ return minstr; }
 			set
 			{
+				if (value == null) {
+					minOccurs = decimal.One;
+					minstr = value;
+					return;
+				}
+
 				decimal val = decimal.Parse(value);
 				if(val >= 0 && (val == Decimal.Truncate(val)))
 				{
@@ -75,6 +86,8 @@ namespace System.Xml.Schema
 						throw new XmlSchemaException
 							("MaxOccurs must be a non-negative integer",null);
 					}
+					if (val == 0 && minstr == null)
+						minOccurs = 0;
 				}
 			}
 		}
@@ -89,7 +102,7 @@ namespace System.Xml.Schema
 			get{ return  minOccurs; }
 			set
 			{
-				MinOccursString = value.ToString();
+				MinOccursString = value.ToString ();
 			}
 		}
 
@@ -99,18 +112,123 @@ namespace System.Xml.Schema
 			get{ return  maxOccurs; } 
 			set
 			{
-				MaxOccursString = value.ToString();
+				MaxOccursString = value.ToString ();
 			}
 		}
 
+		internal decimal ValidatedMinOccurs
+		{
+			get { return validatedMinOccurs; }
+		}
+
+		internal decimal ValidatedMaxOccurs
+		{
+			get { return validatedMaxOccurs; }
+		}
+
+		internal virtual XmlSchemaParticle ActualParticle
+		{
+			get { return this; }
+		}
 		#endregion
 
+		internal void CompileOccurence (ValidationEventHandler h, XmlSchema schema)
+		{
+			if (MinOccurs > MaxOccurs && !(MaxOccurs == 0 && MinOccursString == null))
+				error(h,"minOccurs must be less than or equal to maxOccurs");
+			else {
+				if (MaxOccursString == "unbounded")
+					this.validatedMaxOccurs = decimal.MaxValue;
+				else
+					this.validatedMaxOccurs = maxOccurs;
+				if (this.validatedMaxOccurs == 0)
+					this.validatedMinOccurs = 0;
+				else
+					this.validatedMinOccurs = minOccurs;
+			}
+		}
+
+		internal virtual void ValidateOccurenceRangeOK (XmlSchemaParticle other,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			if ((this.ValidatedMinOccurs < other.ValidatedMinOccurs) ||
+				(other.ValidatedMaxOccurs != decimal.MaxValue &&
+				this.ValidatedMaxOccurs > other.ValidatedMaxOccurs))
+				error (h, "Invalid derivation occurence range was found.");
+		}
+
+		internal virtual decimal GetMinEffectiveTotalRange ()
+		{
+			return 0;
+		}
+
+		internal decimal GetMinEffectiveTotalRangeAllAndSequence ()
+		{
+			if (minEffectiveTotalRange >= 0)
+				return minEffectiveTotalRange;
+
+			decimal product = 0; //this.ValidatedMinOccurs;
+			XmlSchemaObjectCollection col = null;
+			if (this is XmlSchemaAll)
+				col = ((XmlSchemaAll) this).Items;
+			else
+				col = ((XmlSchemaSequence) this).Items;
+			foreach (XmlSchemaParticle p in col)
+				product += p.GetMinEffectiveTotalRange ();
+
+			minEffectiveTotalRange = product;
+			return product;
+		}
+
+		internal virtual bool ValidateIsEmptiable ()
+		{
+			return this.validatedMinOccurs == 0 || this.GetMinEffectiveTotalRange () == 0;
+		}
+
+		internal abstract void ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,
+			ValidationEventHandler h, XmlSchema schema);
+
+		internal abstract void ValidateUniqueParticleAttribution (
+			XmlSchemaObjectTable qnames, ArrayList nsNames,
+			ValidationEventHandler h, XmlSchema schema);
+
+		internal abstract void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
+			ValidationEventHandler h, XmlSchema schema);
+
+		// See http://www.thaiopensource.com/relaxng/simplify.html
+		internal abstract void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema);
+
 		#region Internal Class
 		public class XmlSchemaParticleEmpty : XmlSchemaParticle
 		{
 			internal XmlSchemaParticleEmpty ()
 			{
 			}
+
+			internal override void ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,
+				ValidationEventHandler h, XmlSchema schema)
+			{
+				// TODO
+			}
+
+			internal override void CheckRecursion (int depth, 
+				ValidationEventHandler h, XmlSchema schema)
+			{
+				// do nothing
+			}
+
+			internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames,
+				ArrayList nsNames, ValidationEventHandler h, XmlSchema schema)
+			{
+				// do nothing
+			}
+
+			internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
+				ValidationEventHandler h, XmlSchema schema)
+			{
+				// do nothing
+			}
+
 		}
 		#endregion
 	}

+ 5 - 0
mcs/class/System.XML/System.Xml.Schema/XmlSchemaReader.cs

@@ -30,6 +30,11 @@ namespace System.Xml.Schema
 			get { return NamespaceURI + ":" + LocalName; }
 		}
 
+		public XmlReader Reader
+		{
+			get { return this.reader; }
+		}
+
 		public void RaiseInvalidElementError()
 		{
 			string errstr = "Element "+FullName + " is invalid in this context.\n";

+ 141 - 26
mcs/class/System.XML/System.Xml.Schema/XmlSchemaSequence.cs

@@ -1,6 +1,12 @@
-// Author: Dwivedi, Ajay kumar
-//            [email protected]
+//
+// System.Xml.Schema.XmlSchemaSequence.cs
+//
+// Author:
+//	Dwivedi, Ajay kumar  [email protected]
+//	Atsushi Enomoto  [email protected]
+//
 using System;
+using System.Collections;
 using System.Xml.Serialization;
 using System.Xml;
 
@@ -12,6 +18,7 @@ namespace System.Xml.Schema
 	public class XmlSchemaSequence : XmlSchemaGroupBase
 	{
 		private XmlSchemaObjectCollection items;
+		private XmlSchemaObjectCollection compiledItems;
 		private static string xmlname = "sequence";
 
 		public XmlSchemaSequence()
@@ -28,51 +35,159 @@ namespace System.Xml.Schema
 		{
 			get{ return items; }
 		}
+		internal XmlSchemaObjectCollection CompiledItems 
+		{
+			get{ return compiledItems; }
+		}
+
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
 				return 0;
 
-			//FIXME: Should we reset the values
-			if(MinOccurs > MaxOccurs)
-				error(h,"minOccurs must be less than or equal to maxOccurs");
-
 			XmlSchemaUtil.CompileID(Id, this, schema.IDCollection, h);
+			CompileOccurence (h, schema);
 
 			foreach(XmlSchemaObject obj in Items)
 			{
-				if(obj is XmlSchemaElement)
-				{
-					errorCount += ((XmlSchemaElement)obj).Compile(h,schema);
-				}
-				else if(obj is XmlSchemaGroupRef)
-				{
-					errorCount += ((XmlSchemaGroupRef)obj).Compile(h,schema);
-				}
-				else if(obj is XmlSchemaChoice)
-				{
-					errorCount += ((XmlSchemaChoice)obj).Compile(h,schema);
-				}
-				else if(obj is XmlSchemaSequence)
-				{
-					errorCount += ((XmlSchemaSequence)obj).Compile(h,schema);
-				}
-				else if(obj is XmlSchemaAny)
+				if(obj is XmlSchemaElement ||
+					obj is XmlSchemaGroupRef ||
+					obj is XmlSchemaChoice ||
+					obj is XmlSchemaSequence ||
+					obj is XmlSchemaAny)
 				{
-					errorCount += ((XmlSchemaAny)obj).Compile(h,schema);
+					errorCount += obj.Compile(h,schema);
 				}
+				else
+					error(h, "Invalid schema object was specified in the particles of the sequence model group.");
 			}
 			this.CompilationId = schema.CompilationId;
 			return errorCount;
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
+			if (IsValidated (schema.CompilationId))
+				return errorCount;
+
+			compiledItems = new XmlSchemaObjectCollection ();
+			foreach (XmlSchemaObject obj in Items) {
+				errorCount += obj.Validate (h, schema);
+				compiledItems.Add (obj);
+			}
+
+			ValidationId = schema.ValidationId;
 			return errorCount;
 		}
+
+		internal override void ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			XmlSchemaElement el = baseParticle as XmlSchemaElement;
+			if (el != null) {
+				// Forbidden
+				error (h, "Invalid sequence paricle derivation.");
+				return;
+			}
+
+			XmlSchemaSequence seq = baseParticle as XmlSchemaSequence;
+			if (seq != null) {
+				// Recurse
+				ValidateOccurenceRangeOK (seq, h, schema);
+
+				// FIXME: What is the correct "order preserving" mapping?
+				int baseIndex = 0;
+				for (int i = 0; i < this.Items.Count; i++) {
+					XmlSchemaParticle pd = Items [i] as XmlSchemaParticle;
+					if (seq.Items.Count > baseIndex) {
+						XmlSchemaParticle pb = seq.Items [baseIndex] as XmlSchemaParticle;
+						pd.ActualParticle.ValidateDerivationByRestriction (pb.ActualParticle, h, schema);
+						baseIndex++;
+					}
+					else
+						error (h, "Invalid choice derivation by extension was found.");
+				}
+
+				return;
+			} 
+
+			XmlSchemaAll all = baseParticle as XmlSchemaAll;
+			XmlSchemaAny any = baseParticle as XmlSchemaAny;
+			XmlSchemaChoice choice = baseParticle as XmlSchemaChoice;
+			if (all != null) {
+				// RecurseUnordered
+				XmlSchemaObjectCollection already = new XmlSchemaObjectCollection ();
+				for (int i = 0; i < this.Items.Count; i++) {
+					XmlSchemaElement de = this.Items [i] as XmlSchemaElement;
+					if (de == null) {
+						error (h, "Invalid sequence particle derivation by restriction from all.");
+						continue;
+					}
+					foreach (XmlSchemaElement e in all.Items) {
+						if (e.QualifiedName == de.QualifiedName) {
+							if (already.Contains (e))
+								error (h, "Base element particle is mapped to the derived element particle in a sequence two or more times.");
+							else {
+								already.Add (e);
+								de.ValidateDerivationByRestriction (e, h, schema);
+							}
+						}
+					}
+				}
+				foreach (XmlSchemaElement e in all.Items)
+					if (!already.Contains (e))
+						if (!e.ValidateIsEmptiable ())
+							error (h, "In base -all- particle, mapping-skipped base element which is not emptiable was found.");
+			} else if (any != null) {
+				// NSRecurseCheckCardinality
+				ValidateNSRecurseCheckCardinality (any, h, schema);
+				return;
+			} else if (choice != null) {
+				// TODO: MapAndSum
+			}
+		}
+
+		internal override decimal GetMinEffectiveTotalRange ()
+		{
+			return GetMinEffectiveTotalRangeAllAndSequence ();
+		}
+
+		internal override void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema)
+		{
+			foreach (XmlSchemaParticle p in this.Items)
+				p.CheckRecursion (depth, h, schema);
+		}
+
+		internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames, ArrayList nsNames,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			foreach (XmlSchemaParticle p in this.Items) {
+				p.ValidateUniqueParticleAttribution (qnames, nsNames, h, schema);
+				if (p.ValidatedMinOccurs == p.ValidatedMaxOccurs)
+					break;
+			}
+			XmlSchemaObjectTable tmpTable = new XmlSchemaObjectTable ();
+			ArrayList al = new ArrayList ();
+			for (int i=0; i<Items.Count; i++) {
+				XmlSchemaParticle p1 = Items [i] as XmlSchemaParticle;
+				p1.ValidateUniqueParticleAttribution (tmpTable, al, h, schema);
+				if (p1.ValidatedMinOccurs == p1.ValidatedMaxOccurs) {
+					tmpTable.Clear ();
+					al.Clear ();
+				}
+			}
+		}
+
+		internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			foreach (XmlSchemaParticle p in this.Items)
+				p.ValidateUniqueTypeAttribution (labels, h, schema);
+		}
+
 		//<sequence
 		//  id = ID
 		//  maxOccurs =  (nonNegativeInteger | unbounded)  : 1

+ 16 - 4
mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleContent.cs

@@ -1,5 +1,10 @@
-// Author: Dwivedi, Ajay kumar
-//            [email protected]
+//
+// System.Xml.Schema.XmlSchemaSimpleContent.cs
+//
+// Author:
+//	Dwivedi, Ajay kumar  [email protected]
+//	Atsushi Enomoto  [email protected]
+//
 using System;
 using System.Xml.Serialization;
 using System.Xml;
@@ -13,6 +18,7 @@ namespace System.Xml.Schema
 	{
 		private XmlSchemaContent content;
 		private static string xmlname = "simpleContent";
+		internal object actualBaseSchemaType;
 		public XmlSchemaSimpleContent()
 		{
 		}
@@ -29,7 +35,7 @@ namespace System.Xml.Schema
 		/// 1. Content must be present and one of restriction or extention
 		///</remarks>
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
@@ -61,8 +67,14 @@ namespace System.Xml.Schema
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
+			if (IsValidated (schema.ValidationId))
+				return errorCount;
+
+			errorCount += this.Content.Validate (h, schema);
+
+			ValidationId = schema.ValidationId;
 			return errorCount;
 		}
 		//<simpleContent 

+ 42 - 5
mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleContentExtension.cs

@@ -1,5 +1,10 @@
-// Author: Dwivedi, Ajay kumar
-//            [email protected]
+//
+// System.Xml.Schema.XmlSchemaSimpleContentExtension.cs
+//
+// Author:
+//	Dwivedi, Ajay kumar  [email protected]
+//	Atsushi Enomoto  [email protected]
+//
 using System;
 using System.Xml;
 using System.Xml.Serialization;
@@ -48,15 +53,24 @@ namespace System.Xml.Schema
 		/// 1. Base must be present and a QName
 		///</remarks>
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
 				return 0;
 
+			if (this.isRedefinedComponent) {
+				if (Annotation != null)
+					Annotation.isRedefinedComponent = true;
+				if (AnyAttribute != null)
+					AnyAttribute.isRedefinedComponent = true;
+				foreach (XmlSchemaObject obj in Attributes)
+					obj.isRedefinedComponent = true;
+			}
+
 			if(BaseTypeName == null || BaseTypeName.IsEmpty)
 			{
-				error(h, "base must be present and a QName");
+				error(h, "base must be present, as a QName");
 			}
 			else if(!XmlSchemaUtil.CheckQName(BaseTypeName))
 				error(h,"BaseTypeName must be a QName");
@@ -89,10 +103,33 @@ namespace System.Xml.Schema
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
+			if (IsValidated (schema.ValidationId))
+				return errorCount;
+
+			XmlSchemaType st = schema.SchemaTypes [baseTypeName] as XmlSchemaType;
+			if (st != null) {
+				XmlSchemaComplexType ct = st as XmlSchemaComplexType;
+				if (ct != null && ct.ContentModel is XmlSchemaComplexContent)
+					error (h, "Specified type is complex type which contains complex content.");
+				st.Validate (h, schema);
+				actualBaseSchemaType = st;
+			} else if (baseTypeName == XmlSchemaComplexType.AnyTypeName) {
+				actualBaseSchemaType = XmlSchemaComplexType.AnyType;
+			} else if (baseTypeName.Namespace == XmlSchema.Namespace) {
+				actualBaseSchemaType = XmlSchemaDatatype.FromName (baseTypeName);
+				if (actualBaseSchemaType == null)
+					error (h, "Invalid schema datatype name is specified.");
+			}
+			// otherwise, it might be missing sub components.
+			else if (!schema.missedSubComponents)// && schema.Schemas [baseTypeName.Namespace] != null)
+				error (h, "Referenced base schema type " + baseTypeName + " was not found in the corresponding schema.");
+
+			ValidationId = schema.ValidationId;
 			return errorCount;
 		}
+
 		//<extension 
 		//base = QName 
 		//id = ID 

+ 37 - 3
mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleContentRestriction.cs

@@ -75,15 +75,24 @@ namespace System.Xml.Schema
 		/// 1. Base must be present and a QName
 		///</remarks>
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
 				return 0;
 
+			if (this.isRedefinedComponent) {
+				if (Annotation != null)
+					Annotation.isRedefinedComponent = true;
+				if (AnyAttribute != null)
+					AnyAttribute.isRedefinedComponent = true;
+				foreach (XmlSchemaObject obj in Attributes)
+					obj.isRedefinedComponent = true;
+			}
+
 			if(BaseTypeName == null || BaseTypeName.IsEmpty)
 			{
-				error(h, "base must be present and a QName");
+				error(h, "base must be present, as a QName");
 			}
 			else if(!XmlSchemaUtil.CheckQName(BaseTypeName))
 				error(h,"BaseTypeName must be a QName");
@@ -123,8 +132,33 @@ namespace System.Xml.Schema
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
+			if (IsValidated (schema.ValidationId))
+				return errorCount;
+
+			if (baseType != null) {
+				baseType.Validate (h, schema);
+				actualBaseSchemaType = baseType;
+			}
+			else if (baseTypeName != XmlQualifiedName.Empty) {
+				XmlSchemaType st = schema.SchemaTypes [baseTypeName] as XmlSchemaType;
+				if (st != null) {
+					st.Validate (h, schema);
+					actualBaseSchemaType = st;
+				} else if (baseTypeName == XmlSchemaComplexType.AnyTypeName) {
+					actualBaseSchemaType = XmlSchemaComplexType.AnyType;
+				} else if (baseTypeName.Namespace == XmlSchema.Namespace) {
+					actualBaseSchemaType = XmlSchemaDatatype.FromName (baseTypeName);
+					if (actualBaseSchemaType == null)
+						error (h, "Invalid schema datatype name is specified.");
+				}
+				// otherwise, it might be missing sub components.
+				else if (!schema.missedSubComponents)// && schema.Schemas [baseTypeName.Namespace] != null)
+					error (h, "Referenced base schema type " + baseTypeName + " was not found in the corresponding schema.");
+			}
+
+			ValidationId = schema.ValidationId;
 			return errorCount;
 		}
 

+ 205 - 15
mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleType.cs

@@ -1,8 +1,14 @@
-// Author: Dwivedi, Ajay kumar
-//            [email protected]
+//
+// System.Xml.Schema.XmlSchemaSimpleType.cs
+//
+// Author:
+//	Dwivedi, Ajay kumar  [email protected]
+//	Atsushi Enomoto  [email protected]
+//
 using System;
 using System.Xml.Serialization;
 using System.Xml;
+using Mono.Xml.Schema;
 
 namespace System.Xml.Schema
 {
@@ -11,10 +17,18 @@ namespace System.Xml.Schema
 	/// </summary>
 	public class XmlSchemaSimpleType : XmlSchemaType
 	{
+		static XmlSchemaSimpleType anySimpleType;
+
 		private XmlSchemaSimpleTypeContent content;
 		//compilation vars
 		internal bool islocal = true; // Assuming local means we have to specify islocal=false only in XmlSchema
 		private static string xmlname = "simpleType";
+		private bool recursed;
+		private XmlSchemaDerivationMethod variety;
+
+		internal static XsdAnySimpleType AnySimpleType {
+			get { return XsdAnySimpleType.Instance; }
+		}
 
 		public XmlSchemaSimpleType()
 		{
@@ -29,6 +43,11 @@ namespace System.Xml.Schema
 			set{ content = value; }
 		}
 
+		internal XmlSchemaDerivationMethod Variety
+		{
+			get{ return variety; }
+		}
+
 		/// <remarks>
 		/// For a simple Type:
 		///		1. Content must be present
@@ -49,7 +68,7 @@ namespace System.Xml.Schema
 		///				4.2 otherwise simple ur-type
 		/// </remarks>
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
@@ -61,6 +80,8 @@ namespace System.Xml.Schema
 			{
 				if(this.Name != null) // a.1
 					error(h,"Name is prohibited in a local simpletype");
+				else
+					this.QNameInternal = new XmlQualifiedName(this.Name,schema.TargetNamespace);
 				if(this.Final != XmlSchemaDerivationMethod.None) //a.2
 					error(h,"Final is prohibited in a local simpletype");
 			}
@@ -82,13 +103,9 @@ namespace System.Xml.Schema
 						this.finalResolved = XmlSchemaDerivationMethod.All;
 						break;
 					case XmlSchemaDerivationMethod.List:
-						this.finalResolved = XmlSchemaDerivationMethod.List;
-						break;
 					case XmlSchemaDerivationMethod.Union:
-						this.finalResolved = XmlSchemaDerivationMethod.Union;
-						break;
 					case XmlSchemaDerivationMethod.Restriction:
-						this.finalResolved = XmlSchemaDerivationMethod.Restriction;
+						this.finalResolved = Final;
 						break;
 					default:
 						error(h,"The value of final attribute is not valid for simpleType");
@@ -98,12 +115,17 @@ namespace System.Xml.Schema
 						XmlSchemaDerivationMethod flags = 
 							(XmlSchemaDerivationMethod.Restriction | XmlSchemaDerivationMethod.List |
 							XmlSchemaDerivationMethod.Extension | XmlSchemaDerivationMethod.Union );
-						if(schema.FinalDefault == XmlSchemaDerivationMethod.All)
+						switch (schema.FinalDefault) {
+						case XmlSchemaDerivationMethod.All:
 							finalResolved = XmlSchemaDerivationMethod.All;
-						else if(schema.FinalDefault == XmlSchemaDerivationMethod.None)
-							finalResolved = flags;
-						else 
+							break;
+						case XmlSchemaDerivationMethod.None:
+							finalResolved = XmlSchemaDerivationMethod.Empty;
+							break;
+						default:
 							finalResolved = schema.FinalDefault & flags;
+							break;
+						}
 						break;
 				}
 			}
@@ -114,14 +136,17 @@ namespace System.Xml.Schema
 				error(h,"Content is required in a simpletype");
 			else if(Content is XmlSchemaSimpleTypeRestriction)
 			{
+				this.resolvedDerivedBy = XmlSchemaDerivationMethod.Restriction;
 				errorCount += ((XmlSchemaSimpleTypeRestriction)Content).Compile(h,schema);
 			}
 			else if(Content is XmlSchemaSimpleTypeList)
 			{
+				this.resolvedDerivedBy = XmlSchemaDerivationMethod.List;
 				errorCount += ((XmlSchemaSimpleTypeList)Content).Compile(h,schema);
 			}
 			else if(Content is XmlSchemaSimpleTypeUnion)
 			{
+				this.resolvedDerivedBy = XmlSchemaDerivationMethod.Union;
 				errorCount += ((XmlSchemaSimpleTypeUnion)Content).Compile(h,schema);
 			}
 			this.CompilationId = schema.CompilationId;
@@ -129,14 +154,178 @@ namespace System.Xml.Schema
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h, XmlSchema schema)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
-			if(isCompiled)
+			// 3.14.6 Properties Correct.
+			// 
+			// 1. Post Compilation Properties
+			// {name}, {target namespace} => QNameInternal. Already Compile()d.
+			// {base type definition} => baseSchemaTypeInternal
+			// {final} => finalResolved. Already Compile()d.
+			// {variety} => resolvedDerivedBy. Already Compile()d.
+			//
+			// 2. Should be checked by "recursed" field.
+
+			if(IsValidated (schema.ValidationId))
+				return errorCount;
+
+			if (recursed) {
+				error (h, "Circular type reference was found.");
 				return errorCount;
+			}
+			recursed = true;
+
+			errorCount += content.Validate (h, schema);
+			// BaseSchemaType property
+			this.baseSchemaTypeInternal = content.ActualBaseSchemaType;
+
+			// Datatype property
+			XmlSchemaSimpleType simple = BaseSchemaType as XmlSchemaSimpleType;
+			if (simple != null)
+				this.datatypeInternal = simple.Datatype;
+			else
+				this.datatypeInternal = BaseSchemaType as XmlSchemaDatatype;
+
+			// 3.
+			XmlSchemaSimpleType baseSType = baseSchemaTypeInternal as XmlSchemaSimpleType;
+			if (baseSType != null) {
+				if ((baseSType.FinalResolved & this.DerivedBy) != 0)
+					error (h, "Specified derivation is prohibited by the base simple type.");
+			}
+
+			// {variety}
+			if (this.resolvedDerivedBy == XmlSchemaDerivationMethod.Restriction &&
+				baseSType != null)
+				this.variety = baseSType.Variety;
+			else
+				this.variety = this.resolvedDerivedBy;
+
+			// 3.14.6 Derivation Valid (Restriction, Simple)
+			XmlSchemaSimpleTypeRestriction r = Content as XmlSchemaSimpleTypeRestriction;
+			if (r != null)
+				ValidateDerivationValid (BaseSchemaType, r.Facets, h, schema);
 
+			recursed = false;
+			ValidationId = schema.ValidationId;
 			return errorCount;
 		}
 
+		// 3.14.6 Derivation Valid (RestrictionSimple)
+		internal void ValidateDerivationValid (object baseType, XmlSchemaObjectCollection facets,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			// TODO
+			XmlSchemaSimpleType baseSimpleType = baseType as XmlSchemaSimpleType;
+			switch (this.Variety) {
+			// 1. atomic type
+			case XmlSchemaDerivationMethod.Restriction:
+				// 1.1
+				if (baseSimpleType != null && baseSimpleType.resolvedDerivedBy != XmlSchemaDerivationMethod.Restriction)
+					error (h, "Base schema type is not either atomic type or primitive type.");
+				// 1.2
+				if (baseSimpleType != null && 
+					(baseSimpleType.FinalResolved & XmlSchemaDerivationMethod.Restriction) != 0)
+					error (h, "Derivation by restriction is prohibited by the base simple type.");
+				// TODO: 1.3 facet restriction valid.
+				break;
+			case XmlSchemaDerivationMethod.List:
+				XmlSchemaSimpleTypeList thisList = Content as XmlSchemaSimpleTypeList;
+				/*
+				// 2.1 item list type not allowed
+				if (baseSimpleType != null && baseSimpleType.resolvedDerivedBy == XmlSchemaDerivationMethod.List)
+					error (h, "Base list schema type is not allowed.");
+				XmlSchemaSimpleTypeUnion baseUnion = baseSimpleType.Content as XmlSchemaSimpleTypeUnion;
+				if (baseUnion != null) {
+					bool errorFound = false;
+					foreach (object memberType in baseUnion.ValidatedTypes) {
+						XmlSchemaSimpleType memberST = memberType as XmlSchemaSimpleType;
+						if (memberST != null && memberST.resolvedDerivedBy == XmlSchemaDerivationMethod.List)
+							errorFound = true;
+					}
+					if (errorFound)
+						error (h, "Base union schema type should not contain list types.");
+				}
+				*/
+				// 2.2 facets limited
+				if (facets != null)
+					foreach (XmlSchemaFacet facet in facets) {
+						if (facet is XmlSchemaLengthFacet ||
+							facet is XmlSchemaMaxLengthFacet ||
+							facet is XmlSchemaMinLengthFacet ||
+							facet is XmlSchemaEnumerationFacet ||
+							facet is XmlSchemaPatternFacet)
+							continue;
+						else
+							error (h, "Not allowed facet was found on this simple type which derives list type.");
+					}
+				break;
+			case XmlSchemaDerivationMethod.Union:
+				// 3.1
+
+				// 3.2
+				if (facets != null)
+					foreach (XmlSchemaFacet facet in facets) {
+						if (facet is XmlSchemaEnumerationFacet ||
+							facet is XmlSchemaPatternFacet)
+							continue;
+						else
+							error (h, "Not allowed facet was found on this simple type which derives list type.");
+					}
+				break;
+			}
+		}
+
+		// 3.14.6 Type Derivation OK (Simple)
+		internal bool ValidateTypeDerivationOK (object baseType,
+			ValidationEventHandler h, XmlSchema schema, bool raiseError)
+		{
+			// 1
+			// Note that anyType should also be allowed as anySimpleType.
+			if (this == baseType || baseType == XmlSchemaSimpleType.AnySimpleType ||
+				baseType == XmlSchemaComplexType.AnyType)
+				return true;
+
+			// 2.1
+			XmlSchemaSimpleType baseSimpleType = baseType as XmlSchemaSimpleType;
+			if (baseSimpleType != null && 
+				(baseSimpleType.FinalResolved & resolvedDerivedBy) != 0) {
+				if (raiseError)
+					error (h, "Specified derivation is prohibited by the base type.");
+				return false;
+			}
+
+			// 2.2.1
+			if (BaseSchemaType == baseType)
+				return true;
+
+			// 2.2.2
+			XmlSchemaSimpleType thisBaseSimpleType = BaseSchemaType as XmlSchemaSimpleType;
+			if (thisBaseSimpleType != null) {
+				if (thisBaseSimpleType.ValidateTypeDerivationOK (baseType, h, schema, false))
+					return true;
+			}
+
+			// 2.2.3
+			switch (Variety) {
+			case XmlSchemaDerivationMethod.Union:
+			case XmlSchemaDerivationMethod.List:
+				if (baseType == XmlSchemaSimpleType.AnySimpleType)
+					return true;
+				break;
+			}
+
+			// 2.2.4 validly derived from one of the union member type.
+			if (baseSimpleType != null && baseSimpleType.Variety == XmlSchemaDerivationMethod.Union) {
+				foreach (object memberType in ((XmlSchemaSimpleTypeUnion) baseSimpleType.Content).ValidatedTypes)
+					if (this.ValidateTypeDerivationOK (memberType, h, schema, false))
+						return true;
+			}
+
+			if (raiseError)
+				error(h, "Invalid simple type derivation was found.");
+			return false;
+		}
+
 		//<simpleType 
 		//  final = (#all | (list | union | restriction)) 
 		//  id = ID 
@@ -165,7 +354,8 @@ namespace System.Xml.Schema
 				if(reader.Name == "final")
 				{
 					Exception innerex;
-					stype.Final = XmlSchemaUtil.ReadDerivationAttribute(reader, out innerex, "final");
+					stype.Final = XmlSchemaUtil.ReadDerivationAttribute(reader, out innerex, "final",
+						XmlSchemaUtil.FinalAllowed);
 					if(innerex != null)
 						error(h, "some invalid values not a valid value for final", innerex);
 				}

+ 26 - 0
mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleTypeContent.cs

@@ -13,5 +13,31 @@ namespace System.Xml.Schema
 		{
 		}
 
+		internal object actualBaseSchemaType;
+
+		internal object ActualBaseSchemaType {
+			get { return actualBaseSchemaType; }
+		}
+
+		internal void ValidateActualType (XmlSchemaSimpleType baseType,
+			XmlQualifiedName baseTypeName, ValidationEventHandler h, XmlSchema schema)
+		{
+			XmlSchemaSimpleType type = baseType;
+			if (type == null)
+				type = schema.SchemaTypes [baseTypeName] as XmlSchemaSimpleType;
+			if (type != null) {
+				errorCount += type.Validate (h, schema);
+				actualBaseSchemaType = type;
+			} else if (baseTypeName == XmlSchemaComplexType.AnyTypeName) {
+				actualBaseSchemaType = XmlSchemaComplexType.AnyType;
+			} else if (baseTypeName.Namespace == XmlSchema.Namespace) {
+				actualBaseSchemaType = XmlSchemaDatatype.FromName (baseTypeName);
+				if (actualBaseSchemaType == null)
+					error (h, "Invalid schema type name was specified: " + baseTypeName);
+			}
+			// otherwise, it might be missing sub components.
+			else if (!schema.missedSubComponents)
+				error (h, "Referenced base schema type " + baseTypeName + " was not found in the corresponding schema.");
+		}
 	}
 }

+ 33 - 2
mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleTypeList.cs

@@ -15,6 +15,7 @@ namespace System.Xml.Schema
 		private XmlSchemaSimpleType itemType;
 		private XmlQualifiedName itemTypeName;
 		private static string xmlname = "list";
+		private object validatedListItemType;
 
 		public XmlSchemaSimpleTypeList()
 		{
@@ -40,12 +41,17 @@ namespace System.Xml.Schema
 				itemType = value;
 			}
 		}
+		internal object ValidatedListItemType
+		{
+			get { return validatedListItemType; }
+		}
+
 		/// <remarks>
 		/// 1. One of itemType or a <simpleType> must be present, but not both.
 		/// 2. id must be of type ID
 		/// </remarks>
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
@@ -71,8 +77,33 @@ namespace System.Xml.Schema
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
+			if (IsValidated (schema.ValidationId))
+				return errorCount;
+
+			// As far as I saw, MS.NET handles simpleType.BaseSchemaType as anySimpleType.
+			this.actualBaseSchemaType = XmlSchemaSimpleType.AnySimpleType;
+
+			// ListItemType
+			XmlSchemaSimpleType type = itemType;
+			if (type == null)
+				type = schema.SchemaTypes [itemTypeName] as XmlSchemaSimpleType;
+			if (type != null) {
+				errorCount += type.Validate (h, schema);
+				validatedListItemType = type;
+			} else if (itemTypeName == XmlSchemaComplexType.AnyTypeName) {
+				validatedListItemType = XmlSchemaSimpleType.AnySimpleType;
+			} else if (itemTypeName.Namespace == XmlSchema.Namespace) {
+				validatedListItemType = XmlSchemaDatatype.FromName (itemTypeName);
+				if (validatedListItemType == null)
+					error (h, "Invalid schema type name was specified: " + itemTypeName);
+			}
+			// otherwise, it might be missing sub components.
+			else if (!schema.missedSubComponents)
+				error (h, "Referenced base list item schema type " + itemTypeName + " was not found.");
+
+			ValidationId = schema.ValidationId;
 			return errorCount;
 		}
 		//<list 

+ 8 - 2
mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleTypeRestriction.cs

@@ -60,7 +60,7 @@ namespace System.Xml.Schema
 		/// 3. base must be a valid QName *NO CHECK REQUIRED*
 		/// </remarks>
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
@@ -86,8 +86,14 @@ namespace System.Xml.Schema
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
+			if (IsValidated (schema.ValidationId))
+				return errorCount;
+
+			this.ValidateActualType (baseType, baseTypeName, h, schema);
+
+			ValidationId = schema.ValidationId;
 			return errorCount;
 		}
 		//<restriction 

+ 49 - 2
mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleTypeUnion.cs

@@ -1,6 +1,7 @@
 // Author: Dwivedi, Ajay kumar
 //            [email protected]
 using System;
+using System.Collections;
 using System.Xml;
 using System.Xml.Serialization;
 
@@ -14,6 +15,7 @@ namespace System.Xml.Schema
 		private XmlSchemaObjectCollection baseTypes;
 		private XmlQualifiedName[] memberTypes;
 		private static string xmlname = "union";
+		private object [] validatedTypes;
 
 		public XmlSchemaSimpleTypeUnion()
 		{
@@ -32,12 +34,18 @@ namespace System.Xml.Schema
 			get{ return  memberTypes; } 
 			set{ memberTypes = value; }
 		}
+
+		internal object [] ValidatedTypes
+		{
+			get { return validatedTypes; }
+		}
+
 		/// <remarks>
 		/// 1. Circular union type definition is disallowed. (WTH is this?)
 		/// 2. id must be a valid ID
 		/// </remarks>
 		[MonoTODO]
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
@@ -86,10 +94,49 @@ namespace System.Xml.Schema
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
+			if (IsValidated (schema.ValidationId))
+				return errorCount;
+
+			// As far as I saw, MS.NET handles simpleType.BaseSchemaType as anySimpleType.
+			this.actualBaseSchemaType = XmlSchemaSimpleType.AnySimpleType;
+
+			ArrayList al = new ArrayList ();
+			// Validate MemberTypes
+			if (MemberTypes != null) {
+				foreach (XmlQualifiedName memberTypeName in MemberTypes) {
+					object type = null;
+					XmlSchemaType xstype = schema.SchemaTypes [memberTypeName] as XmlSchemaSimpleType;
+					if (xstype != null) {
+						errorCount += xstype.Validate (h, schema);
+						type = xstype;
+					} else if (memberTypeName == XmlSchemaComplexType.AnyTypeName) {
+						type = XmlSchemaSimpleType.AnySimpleType;
+					} else if (memberTypeName.Namespace == XmlSchema.Namespace) {
+						type = XmlSchemaDatatype.FromName (memberTypeName);
+						if (type == null)
+							error (h, "Invalid schema type name was specified: " + memberTypeName);
+					}
+					// otherwise, it might be missing sub components.
+					else if (!schema.missedSubComponents)
+						error (h, "Referenced base schema type " + memberTypeName + " was not found in the corresponding schema.");
+
+					al.Add (type);
+				}
+			}
+			if (BaseTypes != null) {
+				foreach (XmlSchemaSimpleType st in BaseTypes) {
+					st.Validate (h, schema);
+					al.Add (st);
+				}
+			}
+			this.validatedTypes = al.ToArray ();
+
+			ValidationId = schema.ValidationId;
 			return errorCount;
 		}
+
 		//<union 
 		//  id = ID 
 		//  memberTypes = List of QName 

+ 22 - 9
mcs/class/System.XML/System.Xml.Schema/XmlSchemaType.cs

@@ -12,14 +12,15 @@ namespace System.Xml.Schema
 	/// </summary>
 	public class XmlSchemaType : XmlSchemaAnnotated
 	{
-		internal object BaseSchemaTypeInternal;
-		private XmlSchemaDatatype datatype;
-		private XmlSchemaDerivationMethod derivedBy;
+		internal object baseSchemaTypeInternal;
+		internal XmlSchemaDatatype datatypeInternal;
+		internal XmlSchemaDerivationMethod resolvedDerivedBy;
 		private XmlSchemaDerivationMethod final;
 		internal XmlSchemaDerivationMethod finalResolved;
 		private bool isMixed;
 		private string name;
 		internal XmlQualifiedName QNameInternal;
+		bool recursed;
 
 		public XmlSchemaType()
 		{
@@ -41,6 +42,9 @@ namespace System.Xml.Schema
 			get{ return  final; }
 			set{ final = value; }
 		}
+		#endregion
+
+		#region XmlIgnore
 		[XmlIgnore]
 		public XmlQualifiedName QualifiedName 
 		{
@@ -54,21 +58,18 @@ namespace System.Xml.Schema
 		[XmlIgnore]
 		public object BaseSchemaType 
 		{
-			get{ return  BaseSchemaTypeInternal; }
+			get{ return  baseSchemaTypeInternal; }
 		}
 		[XmlIgnore]
 		public XmlSchemaDerivationMethod DerivedBy 
 		{
-			get{ return derivedBy; }
+			get{ return resolvedDerivedBy; }
 		}
 		[XmlIgnore]
 		public XmlSchemaDatatype Datatype 
 		{
-			get{ return datatype; }
+			get{ return datatypeInternal; }
 		}
-		#endregion
-
-		#region XmlIgnore
 		[XmlIgnore]
 		public virtual bool IsMixed 
 		{  
@@ -77,5 +78,17 @@ namespace System.Xml.Schema
 		}
 		#endregion
 
+		internal bool ValidateRecursionCheck ()
+		{
+			if (recursed)
+				return (this != XmlSchemaComplexType.AnyType);
+			recursed = true;
+			XmlSchemaType baseType = this.BaseSchemaType as XmlSchemaType;
+			bool result = false;
+			if (baseType != null)
+				result = baseType.ValidateRecursionCheck ();
+			recursed = false;
+			return result;
+		}
 	}
 }

+ 4 - 7
mcs/class/System.XML/System.Xml.Schema/XmlSchemaUnique.cs

@@ -20,27 +20,24 @@ namespace System.Xml.Schema
 		/// 2. selector and field must be present
 		/// </remarks>
 		[MonoTODO]
-		internal new int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
-			// If this is already compiled this time, simply skip.
-			if (this.IsComplied (schema.CompilationId))
-				return 0;
-
-			this.CompilationId = schema.CompilationId;
 			return base.Compile(h,schema);
 		}
 		
 		[MonoTODO]
-		internal int Validate(ValidationEventHandler h)
+		internal override int Validate(ValidationEventHandler h, XmlSchema schema)
 		{
 			return errorCount;
 		}
 
+		/*
 		internal new void error(ValidationEventHandler handle, string message)
 		{
 			errorCount++;
 			ValidationHandler.RaiseValidationError(handle, this, message);
 		}
+		*/
 		//<unique 
 		//  id = ID 
 		//  name = NCName 

+ 206 - 12
mcs/class/System.XML/System.Xml.Schema/XmlSchemaUtil.cs

@@ -1,6 +1,8 @@
 using System;
 using System.Xml;
 using System.Collections;
+using Mono.Xml;
+using Mono.Xml.Schema;
 
 namespace System.Xml.Schema
 {
@@ -10,8 +12,47 @@ namespace System.Xml.Schema
 	/// </summary>
 	internal class XmlSchemaUtil
 	{
-		private XmlSchemaUtil()
-		{}
+		static XmlSchemaUtil()
+		{
+			FinalAllowed = XmlSchemaDerivationMethod.Restriction | 
+				XmlSchemaDerivationMethod.Extension;
+			ComplexTypeBlockAllowed = FinalAllowed;
+			ElementBlockAllowed = XmlSchemaDerivationMethod.Substitution | 
+				FinalAllowed;
+		}
+
+		internal static XmlSchemaDerivationMethod FinalAllowed;
+		internal static XmlSchemaDerivationMethod ElementBlockAllowed;
+		internal static XmlSchemaDerivationMethod ComplexTypeBlockAllowed;
+
+		public static void AddToTable (XmlSchemaObjectTable table, XmlSchemaObject obj,
+			XmlQualifiedName qname, ValidationEventHandler h)
+		{
+			if (table.Contains (qname)) {
+				// FIXME: This logic unexpectedly allows 
+				// one redefining item and two or more redefining items.
+				// FIXME: redefining item is not simple replacement,
+				// but much more complex stuff.
+				if (obj.isRedefineChild) {	// take precedence.
+					if (obj.redefinedObject != null)
+						obj.error (h, "Named item " + qname + " was already contained in the schema object table.");
+					else
+						obj.redefinedObject = table [qname];
+					table.Set (qname, obj);
+				}
+				else if (table [qname].isRedefineChild) {
+					if (table [qname].redefinedObject != null)
+						obj.error (h, "Named item " + qname + " was already contained in the schema object table.");
+					else
+						table [qname].redefinedObject = obj;
+					return;	// never add to the table.
+				}
+				else
+					obj.error (h, "Named item " + qname + " was already contained in the schema object table.");
+			}
+			else
+				table.Set (qname, obj);
+		}
 
 		public static void CompileID(string id,  XmlSchemaObject xso, Hashtable idCollection, ValidationEventHandler h)
 		{
@@ -31,7 +72,9 @@ namespace System.Xml.Schema
 		[MonoTODO]
 		public static bool CheckAnyUri(string uri)
 		{
-			 return true;
+			if (uri.StartsWith ("##"))
+				return false;
+			return true;
 		}
 
 		public static bool CheckToken(string token)
@@ -66,8 +109,80 @@ namespace System.Xml.Schema
 
 		public static bool CheckQName(XmlQualifiedName qname)
 		{
+			// What is this doing?
 			return true;
 		}
+
+		public static XmlParserContext GetParserContext (XmlReader reader)
+		{
+			XmlTextReader xtr = reader as XmlTextReader;
+			if (xtr != null)
+				return xtr.GetInternalParserContext ();
+			XmlNodeReader xnr = reader as XmlNodeReader;
+			if (xnr != null)
+				return xnr.GetInternalParserContext ();
+			XmlValidatingReader xvr = reader as XmlValidatingReader;
+			if (xvr != null)
+				return xvr.GetInternalParserContext ();
+			IHasXmlParserContext xctx = reader as IHasXmlParserContext;
+			if (xctx != null)
+				return xctx.ParserContext;
+
+			throw new NotSupportedException ("XmlParserContext cannot be acquired from this XmlReader.");
+		}
+
+		public static bool IsSchemaDatatypeEquals (XsdAnySimpleType st1, object v1,
+			XsdAnySimpleType st2, object v2)
+		{
+			if (v1 == null || v2 == null)
+				return false;
+
+			if (st1 == null)
+				st1 = XmlSchemaSimpleType.AnySimpleType;
+			if (st2 == null)
+				st2 = XmlSchemaSimpleType.AnySimpleType;
+
+			Type t = st2.GetType ();
+			if (st1 is XsdFloat) {
+				return st2 is XsdFloat && Convert.ToSingle (v1) == Convert.ToSingle (v2);
+			} else if (st1 is XsdDouble) {
+				return st2 is XsdDouble && Convert.ToDouble (v1) == Convert.ToDouble (v2);
+			} else if (st1 is XsdDecimal) {
+				if (!(st2 is XsdDecimal) || Convert.ToDecimal (v1) != Convert.ToDecimal (v2))
+					return false;
+				if (st1 is XsdNonPositiveInteger)
+					return st2 is XsdNonPositiveInteger || t == typeof (XsdDecimal) || t == typeof (XsdInteger);
+				else if (st1 is XsdPositiveInteger)
+					return st2 is XsdPositiveInteger || t == typeof (XsdDecimal) || 
+						t == typeof (XsdInteger) || t == typeof (XsdNonNegativeInteger);
+				else if (st1 is XsdUnsignedLong)
+					return st2 is XsdUnsignedLong || t == typeof (XsdDecimal) || 
+						t == typeof (XsdInteger) || t == typeof (XsdNonNegativeInteger);
+				else if (st1 is XsdNonNegativeInteger)
+					return st2 is XsdNonNegativeInteger || t == typeof (XsdDecimal) || t == typeof (XsdInteger);
+				else if (st1 is XsdLong)
+					return st2 is XsdLong || t == typeof (XsdDecimal) || t == typeof (XsdInteger);
+				return true;
+			}
+			else if (!v1.Equals (v2))
+				return false;
+			if (st1 is XsdString) {
+				if (!(st2 is XsdString))
+					return false;
+				if (st1 is XsdNMToken && (st2 is XsdLanguage || st2 is XsdName))
+					return false;
+				if (st2 is XsdNMToken && (st1 is XsdLanguage || st1 is XsdName))
+					return false;
+				if (st1 is XsdName && (st2 is XsdLanguage || st2 is XsdNMToken))
+					return false;
+				if (st2 is XsdName && (st1 is XsdLanguage || st1 is XsdNMToken))
+					return false;
+			}
+			else if (st1 != st2)
+				return false;
+			return true;
+		}
+
 		public static bool IsValidQName(string qname)
 		{
 			foreach(string part in qname.Split(new char[]{':'},2))
@@ -83,7 +198,7 @@ namespace System.Xml.Schema
 		public static string[] SplitList(string list)
 		{
 			if(list == null || list == string.Empty)
-				return new String[0];
+				return new string [0];
 
 			string[] listarr = list.Split(new char[]{' ','\t','\n'});
 			int pos=0;
@@ -151,7 +266,7 @@ namespace System.Xml.Schema
 		// Is some value is read, return it.
 		// If no values return empty.
 		// If exception, return none
-		public static XmlSchemaDerivationMethod ReadDerivationAttribute(XmlReader reader, out Exception innerExcpetion, string name)
+		public static XmlSchemaDerivationMethod ReadDerivationAttribute(XmlReader reader, out Exception innerExcpetion, string name, XmlSchemaDerivationMethod allowed)
 		{
 			innerExcpetion = null;
 			try
@@ -170,19 +285,19 @@ namespace System.Xml.Schema
 					switch(xsdm)
 					{
 						case "":
-							val |= XmlSchemaDerivationMethod.Empty; break;
+							val = AddFlag (val, XmlSchemaDerivationMethod.Empty, allowed); break;
 						case "#all":
-							val |= XmlSchemaDerivationMethod.All; break;
+							val = AddFlag (val,XmlSchemaDerivationMethod.All, allowed); break;
 						case "substitution":
-							val |= XmlSchemaDerivationMethod.Substitution; break;
+							val = AddFlag (val,XmlSchemaDerivationMethod.Substitution, allowed); break;
 						case "extension":
-							val |= XmlSchemaDerivationMethod.Extension; break;
+							val = AddFlag (val,XmlSchemaDerivationMethod.Extension, allowed); break;
 						case "restriction":
-							val |= XmlSchemaDerivationMethod.Restriction; break;
+							val = AddFlag (val,XmlSchemaDerivationMethod.Restriction, allowed); break;
 						case "list":
-							val |= XmlSchemaDerivationMethod.List; break;
+							val = AddFlag (val,XmlSchemaDerivationMethod.List, allowed); break;
 						case "union":
-							val |= XmlSchemaDerivationMethod.Union; break;
+							val = AddFlag (val,XmlSchemaDerivationMethod.Union, allowed); break;
 						default:
 							warn += xsdm + " "; break;
 					}
@@ -198,6 +313,16 @@ namespace System.Xml.Schema
 			}
 		}
 
+		private static XmlSchemaDerivationMethod AddFlag (XmlSchemaDerivationMethod dst,
+			XmlSchemaDerivationMethod add, XmlSchemaDerivationMethod allowed)
+		{
+			if ((add & allowed) == 0 && allowed != XmlSchemaDerivationMethod.All)
+				throw new ArgumentException (add + " is not allowed in this attribute.");
+			if ((dst & add) != 0)
+				throw new ArgumentException (add + " is already specified in this attribute.");
+			return dst | add;
+		}
+
 		public static XmlSchemaForm ReadFormAttribute(XmlReader reader, out Exception innerExcpetion)
 		{
 			innerExcpetion = null;
@@ -295,5 +420,74 @@ namespace System.Xml.Schema
 			qname = new XmlQualifiedName(name,ns);
 			return qname;
 		}
+
+		public static int ValidateAttributesResolved (
+			XmlSchemaObjectTable attributesResolved,
+			ValidationEventHandler h,
+			XmlSchema schema,
+			XmlSchemaObjectCollection attributes,
+			XmlSchemaAnyAttribute anyAttribute,
+			ref XmlSchemaAnyAttribute anyAttributeUse,
+			XmlSchemaAttributeGroup redefined)
+		{
+			int errorCount = 0;
+			if (anyAttribute != null && anyAttributeUse == null)
+				anyAttributeUse = anyAttribute;
+
+			foreach (XmlSchemaObject xsobj in attributes) {
+				XmlSchemaAttributeGroupRef grpRef = xsobj as XmlSchemaAttributeGroupRef;
+				if (grpRef != null) {
+					// Resolve attributeGroup redefinition.
+					XmlSchemaAttributeGroup grp = null;
+					if (redefined != null && grpRef.RefName == redefined.QualifiedName)
+						grp = redefined;
+					else
+						grp = schema.AttributeGroups [grpRef.RefName] as XmlSchemaAttributeGroup;
+					// otherwise, it might be missing sub components.
+					if (grp == null) {
+						if (!schema.missedSubComponents)// && schema.Schemas [grpRef.RefName.Namespace] != null)
+							grpRef.error (h, "Referenced attribute group " + grpRef.RefName + " was not found in the corresponding schema.");
+						continue;
+					}
+					if (grp.AttributeGroupRecursionCheck) {
+						grp.error (h, "Attribute group recursion was found: " + grpRef.RefName);
+						continue;
+					}
+					try {
+						grp.AttributeGroupRecursionCheck = true;
+						errorCount += grp.Validate (h, schema);
+					} finally {
+						grp.AttributeGroupRecursionCheck = false;
+					}
+					if (grp.AnyAttributeUse != null) {
+						// FIXME: should validate wildcard subset validity. See spec 3.10.6
+						if (anyAttribute == null)
+							anyAttributeUse = grp.AnyAttributeUse;
+					}
+					foreach (XmlSchemaAttribute attr in grp.AttributeUses) {
+						if (attr.RefName != null && attr.RefName != XmlQualifiedName.Empty)
+							AddToTable (attributesResolved, attr, attr.RefName, h);
+						else
+							AddToTable (attributesResolved, attr, attr.QualifiedName, h);
+					}
+				} else {
+					XmlSchemaAttribute attr = xsobj as XmlSchemaAttribute;
+					if (attr != null) {
+						errorCount += attr.Validate (h, schema);
+						if (attr.RefName != null && attr.RefName != XmlQualifiedName.Empty)
+							AddToTable (attributesResolved, attr, attr.RefName, h);
+						else
+							AddToTable (attributesResolved, attr, attr.QualifiedName, h);
+					} else {
+						if (anyAttribute == null) {
+							anyAttributeUse = (XmlSchemaAnyAttribute) xsobj;
+							anyAttribute.Validate (h, schema);
+						}
+					}
+				}
+			}
+			return errorCount;
+		}
+
 	}
 }

+ 243 - 1
mcs/class/System.XML/System.Xml.Schema/XmlSchemaXPath.cs

@@ -1,9 +1,12 @@
 // Author: Dwivedi, Ajay kumar
 //            [email protected]
 using System;
+using System.Collections;
 using System.Xml.Serialization;
 using System.ComponentModel;
 using System.Xml;
+using Mono.Xml;
+using Mono.Xml.Schema;
 
 namespace System.Xml.Schema
 {
@@ -13,6 +16,11 @@ namespace System.Xml.Schema
 	public class XmlSchemaXPath : XmlSchemaAnnotated
 	{
 		private string xpath;
+		XmlNamespaceManager nsmgr;
+		internal bool isSelector;
+		XsdIdentityPath [] compiledExpression;
+
+		XsdIdentityPath currentPath;
 
 		public XmlSchemaXPath()
 		{
@@ -25,17 +33,234 @@ namespace System.Xml.Schema
 			set{ xpath = value; }
 		}
 
-		internal int Compile(ValidationEventHandler h, XmlSchema schema)
+		internal override int Compile(ValidationEventHandler h, XmlSchema schema)
 		{
 			// If this is already compiled this time, simply skip.
 			if (this.IsComplied (schema.CompilationId))
 				return 0;
 
+			if (nsmgr == null) {
+				nsmgr = new XmlNamespaceManager (new NameTable ());
+				if (Namespaces != null)
+					foreach (XmlQualifiedName qname in Namespaces.ToArray ())
+						nsmgr.AddNamespace (qname.Name, qname.Namespace);
+			}
+
+			currentPath = new XsdIdentityPath ();
+			ParseExpression (xpath, h, schema);
+
 			XmlSchemaUtil.CompileID(Id, this, schema.IDCollection, h);
 			this.CompilationId = schema.CompilationId;
 			return errorCount;
 		}
 
+		internal XsdIdentityPath [] CompiledExpression {
+			get { return compiledExpression; }
+		}
+
+		private void ParseExpression (string xpath, ValidationEventHandler h, XmlSchema schema)
+		{
+			ArrayList paths = new ArrayList ();
+			ParsePath (xpath, 0, paths, h, schema);
+			this.compiledExpression = (XsdIdentityPath []) paths.ToArray (typeof (XsdIdentityPath));
+		}
+
+		private void ParsePath (string xpath, int pos, ArrayList paths,
+			ValidationEventHandler h, XmlSchema schema)
+		{
+			pos = SkipWhitespace (xpath, pos);
+			if (xpath.Length >= pos + 3 && xpath [pos] == '.') {
+				int tmp = pos;
+				pos++;
+				pos = SkipWhitespace (xpath, pos);
+				if (xpath.Length > pos + 2 && xpath.IndexOf ("//", pos, 2) == pos) {
+					currentPath.Descendants = true;
+					pos += 2;
+				}
+				else
+					pos = tmp;	// revert
+			}
+			ArrayList al = new ArrayList ();
+			ParseStep (xpath, pos, al, paths, h, schema);
+		}
+
+		private void ParseStep (string xpath, int pos, ArrayList steps,
+			ArrayList paths, ValidationEventHandler h, XmlSchema schema)
+		{
+			pos = SkipWhitespace (xpath, pos);
+			if (xpath.Length == pos) {
+				error (h, "Empty xpath expression is specified");
+				return;
+			}
+
+			XsdIdentityStep step = new XsdIdentityStep ();
+			switch (xpath [pos]) {
+			case '@':
+				if (isSelector) {
+					error (h, "Selector cannot include attribute axes.");
+					currentPath = null;
+					return;
+				}
+				pos++;
+				step.IsAttribute = true;
+				pos = SkipWhitespace (xpath, pos);
+				if (xpath.Length > pos && xpath [pos] == '*') {
+					pos++;
+					step.IsAnyName = true;
+					break;
+				}
+				goto default;
+			case '.':
+				pos++;	// do nothing ;-)
+				step.IsCurrent = true;
+				break;
+			case '*':
+				pos++;
+				step.IsAnyName = true;
+				break;
+			case 'c':
+				if (xpath.Length > pos + 5 && xpath.IndexOf ("child", pos, 5) == pos) {
+					int tmp = pos;
+					pos += 5;
+					pos = SkipWhitespace (xpath, pos);
+					if (xpath.Length > pos && xpath [pos] == ':' && xpath [pos+1] == ':') {
+						pos += 2;
+						if (xpath.Length > pos && xpath [pos] == '*') {
+							pos++;
+							step.IsAnyName = true;
+							break;
+						}
+						pos = SkipWhitespace (xpath, pos);
+					}
+					else
+						pos = tmp;
+				}
+				goto default;
+			case 'a':
+				if (xpath.Length > pos + 9 && xpath.IndexOf ("attribute", pos, 9) == pos) {
+					int tmp = pos;
+					pos += 9;
+					pos = SkipWhitespace (xpath, pos);
+					if (xpath.Length > pos && xpath [pos] == ':' && xpath [pos+1] == ':') {
+						if (isSelector) {
+							error (h, "Selector cannot include attribute axes.");
+							currentPath = null;
+							return;
+						}
+						pos += 2;
+						step.IsAttribute = true;
+						if (xpath.Length > pos && xpath [pos] == '*') {
+							pos++;
+							step.IsAnyName = true;
+							break;
+						}
+						pos = SkipWhitespace (xpath, pos);
+					}
+					else
+						pos = tmp;
+				}
+				goto default;
+			default:
+				int nameStart = pos;
+				while (xpath.Length > pos) {
+					if (!XmlChar.IsNCNameChar (xpath [pos]))
+						break;
+					else
+						pos++;
+				}
+				if (pos == nameStart) {
+					error (h, "Invalid path format for a field.");
+					this.currentPath = null;
+					return;
+				}
+				if (xpath.Length == pos || xpath [pos] != ':') {
+					step.Name = xpath.Substring (nameStart, pos - nameStart);
+					break;
+				} else {
+					string prefix = xpath.Substring (nameStart, pos - nameStart);
+					pos++;
+					if (xpath.Length > pos && xpath [pos] == '*') {
+						string ns = nsmgr.LookupNamespace (prefix);
+						if (ns == null) {
+							error (h, "Specified prefix '" + prefix + "' is not declared.");
+							this.currentPath = null;
+							return;
+						}
+						step.Namespace = ns;
+						step.Name = "*";
+						pos++;
+					} else {
+						int localNameStart = pos;
+						while (xpath.Length > pos) {
+							if (!XmlChar.IsNCNameChar (xpath [pos]))
+								break;
+							else
+								pos++;
+						}
+						step.Name = xpath.Substring (localNameStart, pos - localNameStart);
+						string ns = nsmgr.LookupNamespace (prefix);
+						if (ns == null) {
+							error (h, "Specified prefix '" + prefix + "' is not declared.");
+							this.currentPath = null;
+							return;
+						}
+						step.Namespace = ns;
+					}
+					break;
+				}
+				break;
+			}
+			if (!step.IsCurrent)	// Current step is meaningless, other than its representation.
+				steps.Add (step);
+			pos = SkipWhitespace (xpath, pos);
+			if (xpath.Length == pos) {
+				currentPath.OrderedSteps = (XsdIdentityStep []) steps.ToArray (typeof (XsdIdentityStep));
+				paths.Add (currentPath);
+				return;
+			}
+			else if (xpath [pos] == '/') {
+				pos++;
+				if (step.IsAttribute) {
+					error (h, "Unexpected xpath token after Attribute NameTest.");
+					this.currentPath = null;
+					return;
+				}
+				this.ParseStep (xpath, pos, steps, paths, h, schema);
+				if (currentPath == null) // For ValidationEventHandler
+					return;
+				currentPath.OrderedSteps = (XsdIdentityStep []) steps.ToArray (typeof (XsdIdentityStep));
+			} else if (xpath [pos] == '|') {
+				pos++;
+				currentPath.OrderedSteps = (XsdIdentityStep []) steps.ToArray (typeof (XsdIdentityStep));
+				paths.Add (this.currentPath);
+				this.currentPath = new XsdIdentityPath ();
+				this.ParsePath (xpath, pos, paths, h, schema);
+			} else {
+				error (h, "Unexpected xpath token after NameTest.");
+				this.currentPath = null;
+				return;
+			}
+		}
+
+		private int SkipWhitespace (string xpath, int pos)
+		{
+			bool loop = true;
+			while (loop && xpath.Length > pos) {
+				switch (xpath [pos]) {
+				case ' ':
+				case '\t':
+				case '\r':
+				case '\n':
+					pos++;
+					continue;
+				default:
+					loop = false;
+					break;
+				}
+			}
+			return pos;
+		}
+
 		//<selector 
 		//  id = ID 
 		//  xpath = a subset of XPath expression, see below 
@@ -58,6 +283,23 @@ namespace System.Xml.Schema
 			path.LinePosition = reader.LinePosition;
 			path.SourceUri = reader.BaseURI;
 
+			XmlNamespaceManager currentMgr = XmlSchemaUtil.GetParserContext (reader.Reader).NamespaceManager;
+			if (currentMgr != null) {
+				path.nsmgr = new XmlNamespaceManager (reader.NameTable);
+				IEnumerator e = currentMgr.GetEnumerator ();
+				while (e.MoveNext ()) {
+					string prefix = e.Current as string;
+					switch (prefix) {
+					case "xml":
+					case "xmlns":
+						continue;
+					default:
+						path.nsmgr.AddNamespace (prefix, currentMgr.LookupNamespace (prefix));
+						break;
+					}
+				}
+			}
+
 			while(reader.MoveToNextAttribute())
 			{
 				if(reader.Name == "id")