private void EndElementIdentityConstraints(object typedValue, string stringValue, XmlSchemaDatatype datatype)
{
string localName = _context.LocalName;
string namespaceUri = _context.Namespace;
for (int ci = _validationStack.Length - 1; ci >= _startIDConstraint; ci--)
{
// no constraint for this level
if (((ValidationState)(_validationStack[ci])).Constr == null)
{
continue;
}
// else
ConstraintStruct[] constraints = ((ValidationState)_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: " + localName + "\t|\tURI: " + namespaceUri + "\t|\tValue: " + typedValue + "\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(SR.Sch_FieldSingleValueExpected, localName);
}
else
{
// for element, Reader.Value = "";
if (LocalAppContextSwitches.IgnoreEmptyKeySequences)
{
if (typedValue != null && stringValue.Length != 0)
{
laxis.Ks[laxis.Column] = new TypedObject(typedValue, stringValue, datatype);
}
}
else
{
if (typedValue != null)
{
laxis.Ks[laxis.Column] = new TypedObject(typedValue, stringValue, datatype);
}
}
}
}
// EndChildren
laxis.EndElement(localName, namespaceUri);
}
if (constraints[i].axisSelector.EndElement(localName, 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 XmlSchemaValidationException(SR.Sch_MissingKey, constraints[i].constraint.name.ToString(), _sourceUriString, 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??
// KeySequence ks2 = (KeySequence) conuct.qualifiedTable[ks];
SendValidationEvent(new XmlSchemaValidationException(SR.Sch_DuplicateKey,
new string[2] { ks.ToString(), constraints[i].constraint.name.ToString() },
_sourceUriString, 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
// KeySequence ks2 = (KeySequence) conuct.qualifiedTable[ks];
SendValidationEvent(new XmlSchemaValidationException(SR.Sch_DuplicateKey,
new string[2] { ks.ToString(), constraints[i].constraint.name.ToString() },
_sourceUriString, 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)(_validationStack[_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 XmlSchemaValidationException(SR.Sch_UnresolvedKeyref, new string[2] { ks.ToString(), vcs[i].constraint.name.ToString() },
_sourceUriString, ks.PosLine, ks.PosCol));
}
}
}
}
} //End of method