Item::Ptr AtomizeResult::next(DynamicContext *context) { // for $item in (Expr) return // typeswitch ($item) // case $value as atomic value return $value // default $node return fn:data($node) Item::Ptr result = _sub->next(context); while(result.isNull()) { _sub = 0; result = _parent->next(context); if(result.isNull()) { _parent = 0; return 0; } if(result->isNode()) { _sub = ((Node*)result.get())->dmTypedValue(context); result = _sub->next(context); } else if(result->isFunction()) { XMLBuffer buf; buf.set(X("Sequence does not match type (xs:anyAtomicType | node())*")); buf.append(X(" - found item of type ")); result->typeToBuffer(context, buf); buf.append(X(" [err:XPTY0004]")); XQThrow(XPath2TypeMatchException, X("AtomizeResult::next"), buf.getRawBuffer()); } } return result; }
bool SequenceType::ItemType::matches(const Item::Ptr &toBeTested, DynamicContext* context) const { if(toBeTested->isNode()) return matches((const Node::Ptr)toBeTested, context); switch(m_nTestType) { case TEST_ELEMENT: case TEST_ATTRIBUTE: case TEST_SCHEMA_ELEMENT: case TEST_SCHEMA_ATTRIBUTE: case TEST_NODE: case TEST_PI: case TEST_COMMENT: case TEST_TEXT: case TEST_DOCUMENT: case TEST_SCHEMA_DOCUMENT: { return false; } case TEST_ANYTHING: { return true; } case TEST_ATOMIC_TYPE: { if(!toBeTested->isAtomicValue()) return false; return matchesNameType(toBeTested, context); } case TEST_FUNCTION: { if(!toBeTested->isFunction()) return false; if(returnType_ == 0) return true; FunctionRef *func = (FunctionRef*)toBeTested.get(); if(func->getNumArgs() != argTypes_->size()) return false; return true; } } return true; }
virtual Item::Ptr next(DynamicContext *context) { Item::Ptr item = parent_->next(context); if(item.notNull() && item->isFunction() && !itemType_->matches((FunctionRef::Ptr)item, context)) { XPath2MemoryManager *mm = context->getMemoryManager(); VarStoreImpl scope(mm, context->getVariableStore()); scope.setVar(0, XQFunctionCoercion::funcVarName, item); AutoVariableStoreReset vsReset(context, &scope); // funcConvert_ only returns one item item = funcConvert_->createResult(context)->next(context); } return item; }