Item NamespaceURIForPrefixFN::evaluateSingleton(const DynamicContext::Ptr &context) const { const Item prefixItem(m_operands.first()->evaluateSingleton(context)); QXmlName::PrefixCode prefix; if(prefixItem) prefix = context->namePool()->allocatePrefix(prefixItem.stringValue()); else prefix = StandardPrefixes::empty; const Item eleItem(m_operands.last()->evaluateSingleton(context)); Q_ASSERT(eleItem); const QXmlName::NamespaceCode ns = eleItem.asNode().namespaceForPrefix(prefix); if(ns == NamespaceResolver::NoBinding) { /* This is a bit tricky. The default namespace is not considered an in-scope binding * on a node, but the specification for this function do consider it a binding and therefore * the empty string. */ if(prefix == StandardPrefixes::empty) return CommonValues::EmptyString; else return Item(); } else return toItem(AnyURI::fromValue(context->namePool()->stringForNamespace(ns))); }
Item PrefixFromQNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const { const QNameValue::Ptr arg(m_operands.first()->evaluateSingleton(context).as<QNameValue>()); if(!arg) return Item(); const QString prefix(context->namePool()->stringForPrefix(arg->qName().prefix())); if(prefix.isEmpty()) return Item(); else return AtomicString::fromValue(context->namePool()->stringForPrefix(arg->qName().prefix())); }
/** * Performs the actual tracing. */ Item mapToItem(const Item &item, const DynamicContext::Ptr &context) { QTextStream out(stderr); ++m_position; if(m_position == 1) { if(item) { out << qPrintable(m_msg) << " : " << qPrintable(item.stringValue()); } else { out << qPrintable(m_msg) << " : (" << qPrintable(formatType(context->namePool(), CommonSequenceTypes::Empty)) << ")\n"; return Item(); } } else { out << qPrintable(item.stringValue()) << '[' << m_position << "]\n"; } return item; }
Item AttributeNameValidator::evaluateSingleton(const DynamicContext::Ptr &context) const { const Item name(m_operand->evaluateSingleton(context)); const QXmlName qName(name.as<QNameValue>()->qName()); if(qName.namespaceURI() == StandardNamespaces::xmlns) { context->error(QtXmlPatterns::tr("The namespace URI in the name for a " "computed attribute cannot be %1.") .arg(formatURI(CommonNamespaces::XMLNS)), ReportContext::XQDY0044, this); return Item(); /* Silence warning. */ } else if(qName.namespaceURI() == StandardNamespaces::empty && qName.localName() == StandardLocalNames::xmlns) { context->error(QtXmlPatterns::tr("The name for a computed attribute " "cannot have the namespace URI %1 " "with the local name %2.") .arg(formatURI(CommonNamespaces::XMLNS)) .arg(formatKeyword("xmlns")), ReportContext::XQDY0044, this); return Item(); /* Silence warning. */ } else if(!qName.hasPrefix() && qName.hasNamespace()) { return Item(QNameValue::fromValue(context->namePool(), QXmlName(qName.namespaceURI(), qName.localName(), StandardPrefixes::ns0))); } else return name; }
void ItemVerifier::verifyItem(const Item &item, const DynamicContext::Ptr &context) const { if(m_reqType->itemMatches(item)) return; context->error(QtXmlPatterns::tr("The item %1 did not match the required type %2.") .arg(formatData(item.stringValue()), formatType(context->namePool(), m_reqType)), m_errorCode, this); }
void ComputedNamespaceConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const { const Item prefixItem(m_operand1->evaluateSingleton(context)); const QString prefix(prefixItem ? prefixItem.stringValue() : QString()); const Item namespaceItem(m_operand2->evaluateSingleton(context)); const QString namespaceURI(namespaceItem ? namespaceItem.stringValue() : QString()); if(namespaceURI.isEmpty()) { context->error(QtXmlPatterns::tr("In a namespace constructor, the value for a namespace cannot be an empty string."), ReportContext::XTDE0930, this); } /* One optimization could be to store a pointer to * the name pool as a member in order to avoid the virtual call(s). */ const NamePool::Ptr np(context->namePool()); if(!prefix.isEmpty() && !QXmlUtils::isNCName(prefix)) { context->error(QtXmlPatterns::tr("The prefix must be a valid %1, which %2 is not.") .arg(formatType(np, BuiltinTypes::xsNCName), formatKeyword(prefix)), ReportContext::XTDE0920, this); } const QXmlName binding(np->allocateBinding(prefix, namespaceURI)); AnyURI::toQUrl<ReportContext::XTDE0905, DynamicContext::Ptr>(namespaceURI, context, this); if(binding.prefix() == StandardPrefixes::xmlns) { context->error(QtXmlPatterns::tr("The prefix %1 cannot be bound.") .arg(formatKeyword(prefix)), ReportContext::XTDE0920, this); } if((binding.prefix() == StandardPrefixes::xml && binding.namespaceURI() != StandardNamespaces::xml) || (binding.prefix() != StandardPrefixes::xml && binding.namespaceURI() == StandardNamespaces::xml)) { context->error(QtXmlPatterns::tr("Only the prefix %1 can be bound to %2 and vice versa.") .arg(formatKeyword(prefix), formatKeyword(namespaceURI)), ReportContext::XTDE0925, this); } context->outputReceiver()->namespaceBinding(binding); }
Item QNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const { const Item paramURI(m_operands.first()->evaluateSingleton(context)); const QString paramQName(m_operands.last()->evaluateSingleton(context).stringValue()); QString ns; if(paramURI) ns = paramURI.stringValue(); if(!XPathHelper::isQName(paramQName)) { context->error(QtXmlPatterns::tr("%1 is an invalid %2").arg(formatData(paramQName), formatType(context->namePool(), BuiltinTypes::xsQName)), ReportContext::FOCA0002, this); return Item(); } QString prefix; QString lname; XPathHelper::splitQName(paramQName, prefix, lname); const QXmlName n(context->namePool()->allocateQName(ns, lname, prefix)); if(ns.isEmpty()) { if(prefix.isEmpty()) return toItem(QNameValue::fromValue(context->namePool(), n)); else { context->error(QtXmlPatterns::tr( "If the first argument is the empty sequence or " "a zero-length string (no namespace), a prefix " "cannot be specified. Prefix %1 was specified.") .arg(formatKeyword(prefix)), ReportContext::FOCA0002, this); return Item(); /* Silence compiler warning. */ } } else return toItem(QNameValue::fromValue(context->namePool(), n)); }
Item QNameConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const { Q_ASSERT(context); const QString lexQName(m_operand->evaluateSingleton(context).stringValue()); const QXmlName expQName(expandQName<DynamicContext::Ptr, ReportContext::XQDY0074, ReportContext::XQDY0074>(lexQName, context, m_nsResolver, this)); return toItem(QNameValue::fromValue(context->namePool(), expQName)); }
void ContextNodeChecker::checkTargetNode(const QXmlNodeModelIndex &node, const DynamicContext::Ptr &context, const ReportContext::ErrorCode code) const { if(node.root().kind() != QXmlNodeModelIndex::Document) { context->error(QtXmlPatterns::tr("The root node of the second argument " "to function %1 must be a document " "node. %2 is not a document node.") .arg(formatFunction(context->namePool(), signature()), formatData(node)), code, this); } }
Item::Iterator::Ptr InScopePrefixesFN::evaluateSequence(const DynamicContext::Ptr &context) const { const Item e(m_operands.first()->evaluateSingleton(context)); const QVector<QXmlName> nbs(e.asNode().namespaceBindings()); const int len = nbs.size(); const NamePool::Ptr np(context->namePool()); QList<Item> result; for(int i = 0; i < len; ++i) result.append(AtomicString::fromValue(np->stringForPrefix(nbs.at(i).prefix()))); return makeListIterator(result); }
Item LocalNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const { const Item node(m_operands.first()->evaluateSingleton(context)); if(node) { const QXmlName name(node.asNode().name()); if(name.isNull()) return CommonValues::EmptyString; else return AtomicString::fromValue(context->namePool()->stringForLocalName(name.localName())); } else return CommonValues::EmptyString; }
Item NamespaceURIFN::evaluateSingleton(const DynamicContext::Ptr &context) const { const Item node(m_operands.first()->evaluateSingleton(context)); if(node) { const QXmlName name(node.asNode().name()); if(name.isNull()) return CommonValues::EmptyAnyURI; else return toItem(AnyURI::fromValue(context->namePool()->stringForNamespace(name.namespaceURI()))); } else return CommonValues::EmptyAnyURI; }
Item NodeNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const { const Item item(m_operands.first()->evaluateSingleton(context)); if(item) { const QXmlName name(item.asNode().name()); if(name.isNull()) return Item(); else return toItem(QNameValue::fromValue(context->namePool(), name)); } else return Item(); }
Item ResolveQNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const { const Item itemName(m_operands.first()->evaluateSingleton(context)); if(!itemName) return Item(); const NamespaceResolver::Ptr resolver(new NodeNamespaceResolver(m_operands.last()->evaluateSingleton(context))); const QString strName(itemName.stringValue()); const QXmlName name = QNameConstructor::expandQName<DynamicContext::Ptr, ReportContext::FOCA0002, ReportContext::FONS0004>(strName, context, resolver, this); return toItem(QNameValue::fromValue(context->namePool(), name)); }
Item ErrorFN::evaluateSingleton(const DynamicContext::Ptr &context) const { QString msg; switch(m_operands.count()) { case 0: /* No args. */ { context->error(QtXmlPatterns::tr("%1 was called.").arg(formatFunction(context->namePool(), signature())), ReportContext::FOER0000, this); return Item(); } case 3: /* Fallthrough, we don't use the 'error object' param. */ case 2: msg = m_operands.at(1)->evaluateSingleton(context).stringValue(); /* Fall through. */ case 1: { const QNameValue::Ptr qName(m_operands.first()->evaluateSingleton(context).as<QNameValue>()); if(qName) context->error(msg, qName->qName(), this); else context->error(msg, ReportContext::FOER0000, this); return Item(); } default: { Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid number of arguments passed to fn:error."); return Item(); } } }
QXmlName ProcessingInstructionConstructor::evaluateTardata(const DynamicContext::Ptr &context) const { const Item name(m_operand1->evaluateSingleton(context)); return context->namePool()->allocateQName(QString(), name.stringValue()); }
Item LocalNameFromQNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const { const QNameValue::Ptr arg(m_operands.first()->evaluateSingleton(context).as<QNameValue>()); return arg ? toItem(AtomicString::fromValue(context->namePool()->stringForLocalName(arg->qName().localName()))) : Item(); }
DynamicContext::Ptr Template::createContext(const TemplateInvoker *const invoker, const DynamicContext::Ptr &context, const bool isCallTemplate) const { Q_ASSERT(invoker); Q_ASSERT(context); /* We have: * - xsl:params in the target template (if any) which may provide * default values. * - xsl:with-params in the caller (if any) which provides values. * * We need to, for each parameter: * - If the called template provides no default value and the caller * has no value, it's an error * - If the called template has a default value and the caller provides * none, it should be used * - In any case the caller provides a value, it needs to be used. * * Problems to look out for: * * - Each xsl:param is in scope for the subsequent xsl:params. Hence, * the evaluation of one xsl:param can depend on another xsl:param, * and so on * - The focus for xsl:params is different from the focus for * the xsl:with-params * - The xsl:with-params are not in scope for the xsl:params. */ WithParam::Hash withParams(invoker->withParams()); /** * Parameters or not, we must in any case create a new stack frame * for the template invocation since otherwise we will trash our existing * variables. Hence it's as with calling user functions. * * This is especially reproducible with recursive functions. */ DynamicContext::Ptr newStack(context->createStack()); /* We have no parameters, and we have no further error checking to * do in the case of not being xsl:apply-templates, so we need to do nothing. */ if(templateParameters.isEmpty() && (!isCallTemplate || withParams.isEmpty())) return newStack; const DynamicContext::TemplateParameterHash hashedParams(parametersAsHash()); DynamicContext::TemplateParameterHash sewnTogether(hashedParams); const DynamicContext::TemplateParameterHash::iterator end(sewnTogether.end()); for(DynamicContext::TemplateParameterHash::iterator it(sewnTogether.begin()); it != end; ++it) { Expression::Ptr ¶m = it.value(); WithParam::Ptr &withParam = withParams[it.key()]; if(withParam) param = Expression::Ptr(new DynamicContextStore(withParam->sourceExpression(), context)); else if(!param) { /* Ops, no xsl:with-param and no default value to cover up for it. */ context->error(QtXmlPatterns::tr("The parameter %1 is required, but no corresponding %2 is supplied.") .arg(formatKeyword(context->namePool(), it.key()), formatKeyword(QLatin1String("xsl:with-param"))), ReportContext::XTSE0690, this); } } if(isCallTemplate) { /* Find xsl:with-param that has no corresponding xsl:param. */ /* Optimization: candidate for threading? */ const WithParam::Hash::const_iterator end(withParams.constEnd()); for(WithParam::Hash::const_iterator it(withParams.constBegin()); it != end; ++it) { if(!hashedParams.contains(it.key())) raiseXTSE0680(context, it.key(), this); } } newStack->templateParameterStore() = sewnTogether; return newStack; }
Item NamespaceURIFromQNameFN::evaluateSingleton(const DynamicContext::Ptr &context) const { const QNameValue::Ptr arg(m_operands.first()->evaluateSingleton(context).as<QNameValue>()); return arg ? toItem(AnyURI::fromValue(context->namePool()->stringForNamespace(arg->qName().namespaceURI()))) : Item(); }