Item GenericPredicate::evaluateSingleton(const DynamicContext::Ptr &context) const { const Item::Iterator::Ptr focus(m_operand1->evaluateSequence(context)); const DynamicContext::Ptr newContext(context->createFocus()); newContext->setFocusIterator(focus); return mapToItem(focus->next(), newContext); }
Item::Iterator::Ptr ApplyTemplate::evaluateSequence(const DynamicContext::Ptr &context) const { const TemplateMode::Ptr templateMode(effectiveMode(context)); const Template::Ptr &templateMatch = findTemplate(context, templateMode); if(templateMatch) return templateMatch->body->evaluateSequence(templateMatch->createContext(this, context, false)); else { /* None of our templates matched. Proceed with a built-in. */ const Item current(context->contextItem()); // TODO it can be an atomic value? const QXmlNodeModelIndex::NodeKind kind(current.asNode().kind()); if(kind == QXmlNodeModelIndex::Element || kind == QXmlNodeModelIndex::Document) { pDebug() << "No template match, using builtin template for element() | document-node()"; const Item::Iterator::Ptr focusIterator(makeItemMappingIterator<Item>(ConstPtr(this), current.asNode().iterate(QXmlNodeModelIndex::AxisChild), context)); const DynamicContext::Ptr focus(context->createFocus()); focus->setFocusIterator(focusIterator); return makeSequenceMappingIterator<Item>(ConstPtr(this), focusIterator, focus); } return CommonValues::emptyIterator; } }
Item::Iterator::Ptr GenericPredicate::evaluateSequence(const DynamicContext::Ptr &context) const { const Item::Iterator::Ptr focus(m_operand1->evaluateSequence(context)); const DynamicContext::Ptr newContext(context->createFocus()); newContext->setFocusIterator(focus); return makeItemMappingIterator<Item>(ConstPtr(this), focus, newContext); }
void Path::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const { /* Note, we use the old context for m_operand1. */ const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context)); const DynamicContext::Ptr focus(context->createFocus()); focus->setFocusIterator(source); while(source->next()) m_operand2->evaluateToSequenceReceiver(focus); }
Item::Iterator::Ptr Path::evaluateSequence(const DynamicContext::Ptr &context) const { /* Note, we use the old context for m_operand1. */ const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context)); const DynamicContext::Ptr focus(context->createFocus()); focus->setFocusIterator(source); const Item::Iterator::Ptr result(makeSequenceMappingIterator<Item>(ConstPtr(this), source, focus)); if(m_checkXPTY0018) { /* This is an expensive code path, but it should happen very rarely. */ enum FoundItem { FoundNone, FoundNode, FoundAtomicValue } hasFound = FoundNone; Item::List whenChecked; Item next(result->next()); while(next) { const FoundItem found = next.isAtomicValue() ? FoundAtomicValue : FoundNode; if(hasFound != FoundNone && hasFound != found) { /* It's an atomic value and we've already found a node. Mixed content. */ context->error(QtXmlPatterns::tr("The last step in a path must contain either nodes " "or atomic values. It cannot be a mixture between the two."), ReportContext::XPTY0018, this); } else hasFound = found; whenChecked.append(next); next = result->next(); } return makeListIterator(whenChecked); } else return result; }
Item Path::evaluateSingleton(const DynamicContext::Ptr &context) const { /* This function is called if both operands' cardinality is exactly-one. Therefore * we manually go forward in the focus by calling next(). * * We don't check for XPTY0018, only in evaluateSequence(), since if we're guaranteed * to evaluate to one item, we can only evaluate to one node or one atomic value. */ /* Note, we use the old context for m_operand1. */ const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context)); const DynamicContext::Ptr focus(context->createFocus()); focus->setFocusIterator(source); /* This test is needed because if the focus is empty, we don't want to(nor can't) evaluate * the next step. */ // TODO Why are we at all invoked then? if(source->next()) return m_operand2->evaluateSingleton(focus); else return Item(); }