private void EndElementIdentityConstraints() { for (int ci = this.validationStack.Length - 1; ci >= this.startIDConstraint; ci--) { // no constraint for this level if (((ValidationState)(this.validationStack[ci])).Constr == null) { continue; } // else ConstraintStruct[] constraints = ((ValidationState)this.validationStack[ci]).Constr; for (int i = 0; i < constraints.Length; ++i) { // EndChildren // axisFields is not null, but may be empty for (int j = 0; j < constraints[i].axisFields.Count; ++j) { LocatedActiveAxis laxis = (LocatedActiveAxis)constraints[i].axisFields[j]; // check field from here // isMatched is false when nextElement is null. so needn't change this part. if (laxis.isMatched) { Debug.WriteLine("Element Field Filling Value!"); Debug.WriteLine("Name: " + reader.LocalName + "\t|\tURI: " + reader.NamespaceURI + "\t|\tValue: " + reader.TypedValueObject + "\n"); // fill value laxis.isMatched = false; if (laxis.Ks[laxis.Column] != null) { // [field...] should be evaluated to either an empty node-set or a node-set with exactly one member // two matches... already existing field value in the table. SendValidationEvent(Res.Sch_FieldSingleValueExpected, reader.LocalName); } else { // for element, reader.Value = ""; string stringValue = !hasSibling ? textString : textValue.ToString(); // only for identity-constraint exception reporting if (reader.TypedValueObject != null && stringValue.Length != 0) { laxis.Ks[laxis.Column] = new TypedObject(reader.TypedValueObject, stringValue, context.ElementDecl.Datatype); } } } // EndChildren laxis.EndElement(reader.LocalName, reader.NamespaceURI); } if (constraints[i].axisSelector.EndElement(reader.LocalName, reader.NamespaceURI)) { // insert key sequence into hash (+ located active axis tuple leave for later) KeySequence ks = constraints[i].axisSelector.PopKS(); // unqualified keysequence are not allowed switch (constraints[i].constraint.Role) { case CompiledIdentityConstraint.ConstraintRole.Key: if (!ks.IsQualified()) { //Key's fields can't be null... if we can return context node's line info maybe it will be better //only keymissing & keyduplicate reporting cases are necessary to be dealt with... 3 places... SendValidationEvent(new XmlSchemaException(Res.Sch_MissingKey, constraints[i].constraint.name.ToString(), reader.BaseURI, ks.PosLine, ks.PosCol)); } else if (constraints[i].qualifiedTable.Contains(ks)) { // unique or key checking value confliction // for redundant key, reporting both occurings // doesn't work... how can i retrieve value out?? SendValidationEvent(new XmlSchemaException(Res.Sch_DuplicateKey, new string[2] { ks.ToString(), constraints[i].constraint.name.ToString() }, reader.BaseURI, ks.PosLine, ks.PosCol)); } else { constraints[i].qualifiedTable.Add(ks, ks); } break; case CompiledIdentityConstraint.ConstraintRole.Unique: if (!ks.IsQualified()) { continue; } if (constraints[i].qualifiedTable.Contains(ks)) { // unique or key checking confliction SendValidationEvent(new XmlSchemaException(Res.Sch_DuplicateKey, new string[2] { ks.ToString(), constraints[i].constraint.name.ToString() }, reader.BaseURI, ks.PosLine, ks.PosCol)); } else { constraints[i].qualifiedTable.Add(ks, ks); } break; case CompiledIdentityConstraint.ConstraintRole.Keyref: // is there any possibility: // 2 keyrefs: value is equal, type is not // both put in the hashtable, 1 reference, 1 not if (constraints[i].qualifiedTable != null) //Will be null in cases when the keyref is outside the scope of the key, that is not allowed by our impl { if (!ks.IsQualified() || constraints[i].qualifiedTable.Contains(ks)) { continue; } constraints[i].qualifiedTable.Add(ks, ks); } break; } } } } // current level's constraint struct ConstraintStruct[] vcs = ((ValidationState)(this.validationStack[this.validationStack.Length - 1])).Constr; if (vcs != null) { // validating all referencing tables... for (int i = 0; i < vcs.Length; ++i) { if ((vcs[i].constraint.Role == CompiledIdentityConstraint.ConstraintRole.Keyref) || (vcs[i].keyrefTable == null)) { continue; } foreach (KeySequence ks in vcs[i].keyrefTable.Keys) { if (!vcs[i].qualifiedTable.Contains(ks)) { SendValidationEvent(new XmlSchemaException(Res.Sch_UnresolvedKeyref, new string[2] { ks.ToString(), vcs[i].constraint.name.ToString() }, reader.BaseURI, ks.PosLine, ks.PosCol)); } } } } }