// Evaluate the "use" expression against this context node
SequenceIterable use = keydef.getUse();
SequenceIterator useval = use.iterate(xc);
while (true) {
AtomicValue item = (AtomicValue)useval.next();
if (item == null) {
break;
}
BuiltInAtomicType actualItemType = item.getPrimitiveType();
if (foundItemTypes != null) {
foundItemTypes.add(actualItemType);
}
if (!Type.isComparable(actualItemType, soughtItemType, false)) {
// the types aren't comparable
if (keydef.isStrictComparison()) {
XPathException de = new XPathException("Cannot compare " + soughtItemType +
" to " + actualItemType + " using 'eq'");
de.setErrorCode("XPTY0004");
throw de;
} else if (keydef.isConvertUntypedToOther() &&
actualItemType.equals(BuiltInAtomicType.UNTYPED_ATOMIC)) {
item = item.convert(soughtItemType, true, xc).asAtomic();
} else if (keydef.isConvertUntypedToOther() &&
soughtItemType.equals(BuiltInAtomicType.UNTYPED_ATOMIC)) {
// index the item as is
} else {
// simply ignore this key value
continue;
}
}
Object val;
if (soughtItemType.equals(BuiltInAtomicType.UNTYPED_ATOMIC) ||
soughtItemType.equals(BuiltInAtomicType.STRING) ||
soughtItemType.equals(BuiltInAtomicType.ANY_URI)) {
// If the supplied key value is untyped atomic, we build an index using the
// actual type returned by the use expression
// If the supplied key value is a string, there is no match unless the use expression
// returns a string or an untyped atomic value
if (collation == null) {
val = item.getStringValue();
} else {
val = collation.getCollationKey(item.getStringValue());
}
} else {
// Ignore NaN values
if (item.isNaN()) {
break;
}
try {
AtomicValue av = item.convert(soughtItemType, true, xc).asAtomic();
val = av.getXPathComparable(false, collation, xc);
} catch (XPathException err) {
// ignore values that can't be converted to the required type
break;
}
}