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 GenericNamespaceResolver::addBinding(const QXmlName nb) { if(nb.namespaceURI() == StandardNamespaces::UndeclarePrefix) m_bindings.remove(nb.prefix()); else m_bindings.insert(nb.prefix(), nb.namespaceURI()); }
/** * This method is used by the isUPAConform method to check whether @p term and @p otherTerm * are the same resp. match each other. */ static bool termMatches(const XsdTerm::Ptr &term, const XsdTerm::Ptr &otherTerm, const NamePool::Ptr &namePool) { if (term->isElement()) { const XsdElement::Ptr element(term); if (otherTerm->isElement()) { // both, the term and the other term are elements const XsdElement::Ptr otherElement(otherTerm); // if they have the same name they match if (element->name(namePool) == otherElement->name(namePool)) return true; } else if (otherTerm->isWildcard()) { // the term is an element and the other term a wildcard const XsdWildcard::Ptr wildcard(otherTerm); // wildcards using XsdWildcard::absentNamespace, so we have to fix that here QXmlName name = element->name(namePool); if (name.namespaceURI() == StandardNamespaces::empty) name.setNamespaceURI(namePool->allocateNamespace(XsdWildcard::absentNamespace())); // if the wildcards namespace constraint allows the elements name, they match if (XsdSchemaHelper::wildcardAllowsExpandedName(name, wildcard, namePool)) return true; } } else if (term->isWildcard()) { const XsdWildcard::Ptr wildcard(term); if (otherTerm->isElement()) { // the term is a wildcard and the other term an element const XsdElement::Ptr otherElement(otherTerm); // wildcards using XsdWildcard::absentNamespace, so we have to fix that here QXmlName name = otherElement->name(namePool); if (name.namespaceURI() == StandardNamespaces::empty) name.setNamespaceURI(namePool->allocateNamespace(XsdWildcard::absentNamespace())); // if the wildcards namespace constraint allows the elements name, they match if (XsdSchemaHelper::wildcardAllowsExpandedName(name, wildcard, namePool)) return true; } else if (otherTerm->isWildcard()) { // both, the term and the other term are wildcards const XsdWildcard::Ptr otherWildcard(otherTerm); // check if the range of the wildcard overlaps. const XsdWildcard::Ptr intersectionWildcard = XsdSchemaHelper::wildcardIntersection(wildcard, otherWildcard); if (!intersectionWildcard || (intersectionWildcard && !(intersectionWildcard->namespaceConstraint()->variety() != XsdWildcard::NamespaceConstraint::Not && intersectionWildcard->namespaceConstraint()->namespaces().isEmpty()))) return true; } } return false; }
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); }
FunctionSignature::Ptr XSLT10CoreFunctions::retrieveFunctionSignature(const NamePool::Ptr &np, const QXmlName name) { if(StandardNamespaces::fn != name.namespaceURI()) return FunctionSignature::Ptr(); FunctionSignature::Ptr s(functionSignatures().value(name)); if(!s) { /* Alphabetic order. */ if(name.localName() == StandardLocalNames::function_available) { s = addFunction(StandardLocalNames::function_available, 1, 2, CommonSequenceTypes::ExactlyOneBoolean); s->appendArgument(argument(np, "function_name"), CommonSequenceTypes::ExactlyOneString); s->appendArgument(argument(np, "arity"), CommonSequenceTypes::ExactlyOneInteger); } else if(name.localName() == StandardLocalNames::system_property) { s = addFunction(StandardLocalNames::system_property, 1, 1, CommonSequenceTypes::ExactlyOneString); s->appendArgument(argument(np, "property_name"), CommonSequenceTypes::ExactlyOneString); } } return s; }
void AccelTreeBuilder<FromDocument>::startElement(const QXmlName &name, qint64 line, qint64 column) { startStructure(); AccelTree::BasicNodeData data(currentDepth(), currentParent(), QXmlNodeModelIndex::Element, -1, name); m_document->basicData.append(data); if (m_features & SourceLocationsFeature) m_document->sourcePositions.insert(m_document->maximumPreNumber(), qMakePair(line, column)); ++m_preNumber; m_ancestors.push(m_preNumber); ++m_size.top(); m_size.push(0); /* With node constructors, we can receive names for which we have no namespace * constructors, such as in the query '<xs:space/>'. Since the 'xs' prefix has no * NamespaceConstructor in this case, we synthesize the namespace. * * In case we're constructing from an XML document we avoid the call because * although it's redundant, it's on extra virtual call for each element. */ if(!FromDocument) namespaceBinding(QXmlName(name.namespaceURI(), 0, name.prefix())); m_isPreviousAtomic = false; }
QString ExternalEnvironment::retrieveProperty(const QXmlName name) { if(name.namespaceURI() != StandardNamespaces::xslt) return QString(); switch(name.localName()) { case StandardLocalNames::version: return QString::number(ExternalEnvironment::XSLVersion); case StandardLocalNames::vendor: return ExternalEnvironment::Vendor; case StandardLocalNames::vendor_url: return QString(ExternalEnvironment::VendorURL.toString()); case StandardLocalNames::product_name: return ExternalEnvironment::ProductName; case StandardLocalNames::product_version: return ExternalEnvironment::ProductVersion; case StandardLocalNames::is_schema_aware: return toString(ExternalEnvironment::IsSchemaAware); case StandardLocalNames::supports_serialization: return toString(ExternalEnvironment::SupportsSerialization); case StandardLocalNames::supports_backwards_compatibility: return toString(ExternalEnvironment::SupportsBackwardsCompatibility); default: return QString(); } }
QString SystemPropertyFN::retrieveProperty(const QXmlName name) { if(name.namespaceURI() != StandardNamespaces::xslt) return QString(); switch(name.localName()) { case StandardLocalNames::version: /* * The supported XSL-T version. * * @see <a href="http://www.w3.org/TR/xslt20/#system-property">The Note paragraph * at the very end of XSL Transformations (XSLT) Version 2.0, * 16.6.5 system-property</a> */ return QString::number(1.20); case StandardLocalNames::vendor: return QLatin1String("Digia Plc and/or its subsidiary(-ies), a Digia Company"); case StandardLocalNames::vendor_url: return QLatin1String("http://qt.digia.com/"); case StandardLocalNames::product_name: return QLatin1String("QtXmlPatterns"); case StandardLocalNames::product_version: return QLatin1String("0.1"); case StandardLocalNames::is_schema_aware: /* Fallthrough. */ case StandardLocalNames::supports_backwards_compatibility: /* Fallthrough. */ case StandardLocalNames::supports_serialization: /* Fallthrough. */ return QLatin1String("no"); default: return QString(); } }
QString NamePool::displayName(const QXmlName qName) const { QReadLocker l(mutableLock()); if(qName.hasNamespace()) { const QString &p = displayPrefix(qName.namespaceURI()); if(p.isEmpty()) return QLatin1Char('{') + m_namespaces.at(qName.namespaceURI()) + QLatin1Char('}') + toLexical(qName); else return p + QLatin1Char(':') + m_localNames.at(qName.localName()); } else return m_localNames.at(qName.localName()); }
void ReportContext::error(const QString &msg, const QXmlName qname, const SourceLocationReflection *const reflection) { Q_ASSERT(!qname.isNull()); createError(msg, QtFatalMsg, QUrl(namePool()->stringForNamespace(qname.namespaceURI()) + QLatin1Char('#') + namePool()->stringForLocalName(qname.localName())), lookupSourceLocation(reflection)); }
QString NamePool::displayName(const QXmlName qName) const { QReadLocker l(&lock); if(qName.hasNamespace()) { if(qName.namespaceURI() == StandardNamespaces::InternalXSLT) return QLatin1Char('#') + m_localNames.at(qName.localName()); const QString &p = displayPrefix(qName.namespaceURI()); if(p.isEmpty()) return QLatin1Char('{') + m_namespaces.at(qName.namespaceURI()) + QLatin1Char('}') + toLexical(qName); else return p + QLatin1Char(':') + m_localNames.at(qName.localName()); } else return m_localNames.at(qName.localName()); }
/*! \internal */ bool QXmlSerializer::isBindingInScope(const QXmlName nb) const { Q_D(const QXmlSerializer); const int levelLen = d->namespaces.size(); if(nb.prefix() == StandardPrefixes::empty) { for(int lvl = levelLen - 1; lvl >= 0; --lvl) { const QVector<QXmlName> &scope = d->namespaces.at(lvl); const int vectorLen = scope.size(); for(int s = vectorLen - 1; s >= 0; --s) { const QXmlName &nsb = scope.at(s); if(nsb.prefix() == StandardPrefixes::empty) return nsb.namespaceURI() == nb.namespaceURI(); } } } else { for(int lvl = 0; lvl < levelLen; ++lvl) { const QVector<QXmlName> &scope = d->namespaces.at(lvl); const int vectorLen = scope.size(); for(int s = 0; s < vectorLen; ++s) { const QXmlName &n = scope.at(s); if (n.prefix() == nb.prefix() && n.namespaceURI() == nb.namespaceURI()) return true; } } } return false; }
/*! \reimp */ void QXmlSerializer::namespaceBinding(const QXmlName &nb) { /* * Writes out \a nb. * * Namespace bindings aren't looked up in a cache, because * we typically receive very few. */ Q_D(QXmlSerializer); Q_ASSERT_X(!nb.isNull(), Q_FUNC_INFO, "It makes no sense to pass a null QXmlName."); Q_ASSERT_X((nb.namespaceURI() != StandardNamespaces::empty) || (nb.prefix() == StandardPrefixes::empty), Q_FUNC_INFO, "Undeclarations of prefixes aren't allowed in XML 1.0 " "and aren't supposed to be received."); if(nb.namespaceURI() == QPatternist::StandardNamespaces::StopNamespaceInheritance) return; if(isBindingInScope(nb)) return; d->namespaces.top().append(nb); if(nb.prefix() == StandardPrefixes::empty) write(" xmlns"); else { write(" xmlns:"); write(d->np->stringForPrefix(nb.prefix())); } write("=\""); writeEscapedAttribute(d->np->stringForNamespace(nb.namespaceURI())); d->write('"'); }
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; }
QString NamePool::toClarkName(const QXmlName &name) const { if(name.isNull()) return QLatin1String("QXmlName(null)"); else { if(name.hasNamespace()) { const QString ns(stringForNamespace(name.namespaceURI())); const QString p(stringForPrefix(name.prefix())); const QString l(stringForLocalName(name.localName())); return QChar::fromLatin1('{') + ns + QChar::fromLatin1('}') + (p.isEmpty() ? l : p + QChar::fromLatin1(':') + l); } else return stringForLocalName(name.localName()); } }
bool ElementAvailableFN::evaluateEBV(const DynamicContext::Ptr &context) const { const Item arg(m_operands.first()->evaluateSingleton(context)); const QString stringName(arg.stringValue()); const QXmlName elementName(QNameConstructor::expandQName<DynamicContext::Ptr, ReportContext::XTDE1440, ReportContext::XTDE1440>(stringName, context, staticNamespaces(), this, false)); if(elementName.namespaceURI() != StandardNamespaces::xslt) return false; QString prefix; QString localName; XPathHelper::splitQName(stringName, prefix, localName); return m_xsltInstructions.contains(localName); }
QPatternist::SequenceType::Ptr ExternalSourceLoader::announceExternalVariable(const QXmlName name, const QPatternist::SequenceType::Ptr &declaredType) { pDebug() << "ExternalSourceLoader::announceExternalVariable()"; Q_ASSERT(!name.isNull()); Q_ASSERT(declaredType); Q_UNUSED(declaredType); /* Needed when bulding in release mode. */ if(name.namespaceURI() == QPatternist::StandardNamespaces::empty) { const VariableValue variable(m_variableMap.value(Global::namePool()->stringForLocalName(name.localName()))); if(variable.first.isEmpty()) return QPatternist::SequenceType::Ptr(); else { /* If announceDocument() can't load a document for uriForVar, it will return * null, which we will too, which is fine, since we can't supply a value for * this variable then. */ if(variable.second == Document) return m_resourceLoader->announceDocument(variable.first, QPatternist::ResourceLoader::WillUse); else if(variable.second == URI) { return QPatternist::CommonSequenceTypes::ExactlyOneString; } else { /* The type is Query, and we don't pre-load * them. No particular reason, just not worth it. */ return QPatternist::CommonSequenceTypes::ZeroOrMoreItems; } } } else return QPatternist::SequenceType::Ptr(); }
FunctionSignature::Ptr XPath10CoreFunctions::retrieveFunctionSignature(const NamePool::Ptr &np, const QXmlName name) { if(StandardNamespaces::fn != name.namespaceURI()) return FunctionSignature::Ptr(); FunctionSignature::Ptr s(functionSignatures().value(name)); if(!s) { const QXmlName::LocalNameCode localName(name.localName()); /* Alphabetic order. */ if(StandardLocalNames::boolean == localName) { s = addFunction(StandardLocalNames::boolean, 1, 1, CommonSequenceTypes::ExactlyOneBoolean); s->appendArgument(argument(np, "arg"), CommonSequenceTypes::EBV); } else if(StandardLocalNames::ceiling == localName) { s = addFunction(StandardLocalNames::ceiling, 1, 1, CommonSequenceTypes::ZeroOrOneNumeric, Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNumeric); } else if(StandardLocalNames::concat == localName) { s = addFunction(StandardLocalNames::concat, 2, FunctionSignature::UnlimitedArity, CommonSequenceTypes::ExactlyOneString); s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrOneAtomicType); s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrOneAtomicType); } else if(StandardLocalNames::contains == localName) { s = addFunction(StandardLocalNames::contains, 2, 3, CommonSequenceTypes::ExactlyOneBoolean, Expression::LastOperandIsCollation); s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrOneString); s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrOneString); s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString); } else if(StandardLocalNames::count == localName) { s = addFunction(StandardLocalNames::count, 1, 1, CommonSequenceTypes::ExactlyOneInteger, Expression::IDCountFN); s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreItems); } else if(StandardLocalNames::False == localName) { s = addFunction(StandardLocalNames::False, 0, 0, CommonSequenceTypes::ExactlyOneBoolean); } else if(StandardLocalNames::floor == localName) { s = addFunction(StandardLocalNames::floor, 1, 1, CommonSequenceTypes::ZeroOrOneNumeric, Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNumeric); } else if(StandardLocalNames::id == localName) { s = addFunction(StandardLocalNames::id, 1, 2, CommonSequenceTypes::ZeroOrMoreElements, Expression::UseContextItem); s->appendArgument(argument(np, "idrefs"), CommonSequenceTypes::ZeroOrMoreStrings); s->appendArgument(argument(np, "node"), CommonSequenceTypes::ExactlyOneNode); } else if(StandardLocalNames::lang == localName) { s = addFunction(StandardLocalNames::lang, 1, 2, CommonSequenceTypes::ExactlyOneBoolean, Expression::UseContextItem); s->appendArgument(argument(np, "testLang"), CommonSequenceTypes::ZeroOrOneString); s->appendArgument(argument(np, "node"), CommonSequenceTypes::ExactlyOneNode); } else if(StandardLocalNames::last == localName) { s = addFunction(StandardLocalNames::last, 0, 0, CommonSequenceTypes::ExactlyOneInteger, Expression::DisableElimination | Expression::RequiresFocus); } else if(StandardLocalNames::local_name == localName) { s = addFunction(StandardLocalNames::local_name, 0, 1, CommonSequenceTypes::ExactlyOneString, Expression::UseContextItem); s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNode); } else if(StandardLocalNames::name == localName) { s = addFunction(StandardLocalNames::name, 0, 1, CommonSequenceTypes::ExactlyOneString, Expression::UseContextItem); s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNode); } else if(StandardLocalNames::namespace_uri == localName) { s = addFunction(StandardLocalNames::namespace_uri, 0, 1, CommonSequenceTypes::ExactlyOneAnyURI, Expression::UseContextItem); s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNode); } else if(StandardLocalNames::normalize_space == localName) { s = addFunction(StandardLocalNames::normalize_space, 0, 1, CommonSequenceTypes::ExactlyOneString, Expression::UseContextItem); s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneString); } else if(StandardLocalNames::Not == localName) { s = addFunction(StandardLocalNames::Not, 1, 1, CommonSequenceTypes::ExactlyOneBoolean); s->appendArgument(argument(np, "arg"), CommonSequenceTypes::EBV); } else if(StandardLocalNames::number == localName) { s = addFunction(StandardLocalNames::number, 0, 1, CommonSequenceTypes::ExactlyOneDouble, Expression::UseContextItem); s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneAtomicType); } else if(StandardLocalNames::position == localName) { s = addFunction(StandardLocalNames::position, 0, 0, CommonSequenceTypes::ExactlyOneInteger, Expression::DisableElimination | Expression::RequiresFocus); } else if(StandardLocalNames::round == localName) { s = addFunction(StandardLocalNames::round, 1, 1, CommonSequenceTypes::ZeroOrOneNumeric, Expression::EmptynessFollowsChild | Expression::RewriteToEmptyOnEmpty); s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneNumeric); } else if(StandardLocalNames::starts_with == localName) { s = addFunction(StandardLocalNames::starts_with, 2, 3, CommonSequenceTypes::ExactlyOneBoolean, Expression::LastOperandIsCollation); s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrOneString); s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrOneString); s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString); } else if(StandardLocalNames::string == localName) { s = addFunction(StandardLocalNames::string, 0, 1, CommonSequenceTypes::ExactlyOneString, Expression::UseContextItem); s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneItem); } else if(StandardLocalNames::string_length == localName) { s = addFunction(StandardLocalNames::string_length, 0, 1, CommonSequenceTypes::ExactlyOneInteger, Expression::UseContextItem); s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneString); } else if(StandardLocalNames::substring == localName) { s = addFunction(StandardLocalNames::substring, 2, 3, CommonSequenceTypes::ExactlyOneString); s->appendArgument(argument(np, "sourceString"), CommonSequenceTypes::ZeroOrOneString); s->appendArgument(argument(np, "startingLoc"), CommonSequenceTypes::ExactlyOneDouble); s->appendArgument(argument(np, "length"), CommonSequenceTypes::ExactlyOneDouble); } else if(StandardLocalNames::substring_after == localName) { s = addFunction(StandardLocalNames::substring_after, 2, 3, CommonSequenceTypes::ExactlyOneString, Expression::LastOperandIsCollation); s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrOneString); s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrOneString); s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString); } else if(StandardLocalNames::substring_before == localName) { s = addFunction(StandardLocalNames::substring_before, 2, 3, CommonSequenceTypes::ExactlyOneString, Expression::LastOperandIsCollation); s->appendArgument(argument(np, "arg1"), CommonSequenceTypes::ZeroOrOneString); s->appendArgument(argument(np, "arg2"), CommonSequenceTypes::ZeroOrOneString); s->appendArgument(argument(np, "collation"), CommonSequenceTypes::ExactlyOneString); } else if(StandardLocalNames::sum == localName) { s = addFunction(StandardLocalNames::sum, 1, 2, CommonSequenceTypes::ZeroOrOneAtomicType); s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrMoreAtomicTypes); s->appendArgument(argument(np, "zero"), CommonSequenceTypes::ZeroOrOneAtomicType); } else if(StandardLocalNames::translate == localName) { s = addFunction(StandardLocalNames::translate, 3, 3, CommonSequenceTypes::ExactlyOneString); s->appendArgument(argument(np, "arg"), CommonSequenceTypes::ZeroOrOneString); s->appendArgument(argument(np, "mapString"), CommonSequenceTypes::ExactlyOneString); s->appendArgument(argument(np, "transString"), CommonSequenceTypes::ExactlyOneString); } else if(StandardLocalNames::True == localName) { s = addFunction(StandardLocalNames::True, 0, 0, CommonSequenceTypes::ExactlyOneBoolean); } } return s; }
/** * This method is used by the subsumes algorithm to check whether the @p derivedTerm is validly derived from the @p baseTerm. * * @param baseTerm The term of the base component (type or group). * @param derivedTerm The term of the derived component (type or group). * @param particles A hash to map the passed base and derived term to the particles they belong to. * @param context The schema context. * @param errorMsg The error message in the case that an error occurs. */ static bool derivedTermValid(const XsdTerm::Ptr &baseTerm, const XsdTerm::Ptr &derivedTerm, const QHash<XsdTerm::Ptr, XsdParticle::Ptr> &particles, const XsdSchemaContext::Ptr &context, QString &errorMsg) { const NamePool::Ptr namePool(context->namePool()); // find the particles where the base and derived term belongs to const XsdParticle::Ptr baseParticle = particles.value(baseTerm); const XsdParticle::Ptr derivedParticle = particles.value(derivedTerm); // check that an empty particle can not be derived from a non-empty particle if (derivedParticle && baseParticle) { if (XsdSchemaHelper::isParticleEmptiable(derivedParticle) && !XsdSchemaHelper::isParticleEmptiable(baseParticle)) { errorMsg = QtXmlPatterns::tr("Empty particle cannot be derived from non-empty particle."); return false; } } if (baseTerm->isElement()) { const XsdElement::Ptr element(baseTerm); if (derivedTerm->isElement()) { // if both terms are elements const XsdElement::Ptr derivedElement(derivedTerm); // check names are equal if (element->name(namePool) != derivedElement->name(namePool)) { errorMsg = QtXmlPatterns::tr("Derived particle is missing element %1.").arg(formatKeyword(element->displayName(namePool))); return false; } // check value constraints are equal (if available) if (element->valueConstraint() && element->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) { if (!derivedElement->valueConstraint()) { errorMsg = QtXmlPatterns::tr("Derived element %1 is missing value constraint as defined in base particle.").arg(formatKeyword(derivedElement->displayName(namePool))); return false; } if (derivedElement->valueConstraint()->variety() != XsdElement::ValueConstraint::Fixed) { errorMsg = QtXmlPatterns::tr("Derived element %1 has weaker value constraint than base particle.").arg(formatKeyword(derivedElement->displayName(namePool))); return false; } const QSourceLocation dummyLocation(QUrl(QLatin1String("http://dummy.org")), 1, 1); const XsdTypeChecker checker(context, QVector<QXmlName>(), dummyLocation); if (!checker.valuesAreEqual(element->valueConstraint()->value(), derivedElement->valueConstraint()->value(), derivedElement->type())) { errorMsg = QtXmlPatterns::tr("Fixed value constraint of element %1 differs from value constraint in base particle.").arg(formatKeyword(derivedElement->displayName(namePool))); return false; } } // check that a derived element can not be nillable if the base element is not nillable if (!element->isNillable() && derivedElement->isNillable()) { errorMsg = QtXmlPatterns::tr("Derived element %1 cannot be nillable as base element is not nillable.").arg(formatKeyword(derivedElement->displayName(namePool))); return false; } // check that the constraints of the derived element are more strict then the constraints of the base element const XsdElement::BlockingConstraints baseConstraints = element->disallowedSubstitutions(); const XsdElement::BlockingConstraints derivedConstraints = derivedElement->disallowedSubstitutions(); if (((baseConstraints & XsdElement::RestrictionConstraint) && !(derivedConstraints & XsdElement::RestrictionConstraint)) || ((baseConstraints & XsdElement::ExtensionConstraint) && !(derivedConstraints & XsdElement::ExtensionConstraint)) || ((baseConstraints & XsdElement::SubstitutionConstraint) && !(derivedConstraints & XsdElement::SubstitutionConstraint))) { errorMsg = QtXmlPatterns::tr("Block constraints of derived element %1 must not be more weaker than in the base element.").arg(formatKeyword(derivedElement->displayName(namePool))); return false; } // if the type of both elements is the same we can stop testing here if (element->type()->name(namePool) == derivedElement->type()->name(namePool)) return true; // check that the type of the derived element can validly derived from the type of the base element if (derivedElement->type()->isSimpleType()) { if (!XsdSchemaHelper::isSimpleDerivationOk(derivedElement->type(), element->type(), SchemaType::DerivationConstraints())) { errorMsg = QtXmlPatterns::tr("Simple type of derived element %1 cannot be validly derived from base element.").arg(formatKeyword(derivedElement->displayName(namePool))); return false; } } else if (derivedElement->type()->isComplexType()) { if (!XsdSchemaHelper::isComplexDerivationOk(derivedElement->type(), element->type(), SchemaType::DerivationConstraints())) { errorMsg = QtXmlPatterns::tr("Complex type of derived element %1 cannot be validly derived from base element.").arg(formatKeyword(derivedElement->displayName(namePool))); return false; } } // if both, derived and base element, have a complex type that contains a particle itself, apply the subsumes algorithm // recursive on their particles if (element->type()->isComplexType() && derivedElement->type()->isComplexType()) { if (element->type()->isDefinedBySchema() && derivedElement->type()->isDefinedBySchema()) { const XsdComplexType::Ptr baseType(element->type()); const XsdComplexType::Ptr derivedType(derivedElement->type()); if ((baseType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || baseType->contentType()->variety() == XsdComplexType::ContentType::Mixed) && (derivedType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || derivedType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) { return XsdParticleChecker::subsumes(baseType->contentType()->particle(), derivedType->contentType()->particle(), context, errorMsg); } } } return true; } else if (derivedTerm->isWildcard()) { // derive a wildcard from an element is not allowed errorMsg = QtXmlPatterns::tr("Element %1 is missing in derived particle.").arg(formatKeyword(element->displayName(namePool))); return false; } } else if (baseTerm->isWildcard()) { const XsdWildcard::Ptr wildcard(baseTerm); if (derivedTerm->isElement()) { // the base term is a wildcard and derived term an element const XsdElement::Ptr derivedElement(derivedTerm); // wildcards using XsdWildcard::absentNamespace, so we have to fix that here QXmlName name = derivedElement->name(namePool); if (name.namespaceURI() == StandardNamespaces::empty) name.setNamespaceURI(namePool->allocateNamespace(XsdWildcard::absentNamespace())); // check that name of the element is allowed by the wildcards namespace constraint if (!XsdSchemaHelper::wildcardAllowsExpandedName(name, wildcard, namePool)) { errorMsg = QtXmlPatterns::tr("Element %1 does not match namespace constraint of wildcard in base particle.").arg(formatKeyword(derivedElement->displayName(namePool))); return false; } } else if (derivedTerm->isWildcard()) { // both, derived and base term are wildcards const XsdWildcard::Ptr derivedWildcard(derivedTerm); // check that the derived wildcard is a valid subset of the base wildcard if (!XsdSchemaHelper::isWildcardSubset(derivedWildcard, wildcard)) { errorMsg = QtXmlPatterns::tr("Wildcard in derived particle is not a valid subset of wildcard in base particle."); return false; } if (!XsdSchemaHelper::checkWildcardProcessContents(wildcard, derivedWildcard)) { errorMsg = QtXmlPatterns::tr("processContent of wildcard in derived particle is weaker than wildcard in base particle."); return false; } } return true; } return false; }
void AccelTree::copyNodeTo(const QXmlNodeModelIndex &node, QAbstractXmlReceiver *const receiver, const NodeCopySettings &settings) const { /* This code piece can be seen as a customized version of * QAbstractXmlReceiver::item/sendAsNode(). */ Q_ASSERT(receiver); Q_ASSERT(!node.isNull()); typedef QHash<QXmlName::PrefixCode, QXmlName::NamespaceCode> Binding; QStack<Binding> outputted; switch(node.kind()) { case QXmlNodeModelIndex::Element: { outputted.push(Binding()); /* Add the namespace for our element name. */ const QXmlName elementName(node.name()); receiver->startElement(elementName); if(!settings.testFlag(InheritNamespaces)) receiver->namespaceBinding(QXmlName(StandardNamespaces::StopNamespaceInheritance, 0, StandardPrefixes::StopNamespaceInheritance)); if(settings.testFlag(PreserveNamespaces)) node.sendNamespaces(receiver); else { /* Find the namespaces that we actually use and add them to outputted. These are drawn * from the element name, and the node's attributes. */ outputted.top().insert(elementName.prefix(), elementName.namespaceURI()); const QXmlNodeModelIndex::Iterator::Ptr attributes(iterate(node, QXmlNodeModelIndex::AxisAttribute)); QXmlNodeModelIndex attr(attributes->next()); while(!attr.isNull()) { const QXmlName &attrName = attr.name(); outputted.top().insert(attrName.prefix(), attrName.namespaceURI()); attr = attributes->next(); } Binding::const_iterator it(outputted.top().constBegin()); const Binding::const_iterator end(outputted.top().constEnd()); for(; it != end; ++it) receiver->namespaceBinding(QXmlName(it.value(), 0, it.key())); } /* Send the attributes of the element. */ { QXmlNodeModelIndex::Iterator::Ptr attributes(node.iterate(QXmlNodeModelIndex::AxisAttribute)); QXmlNodeModelIndex attribute(attributes->next()); while(!attribute.isNull()) { const QString &v = attribute.stringValue(); receiver->attribute(attribute.name(), QStringRef(&v)); attribute = attributes->next(); } } /* Send the children of the element. */ copyChildren(node, receiver, settings); receiver->endElement(); outputted.pop(); break; } case QXmlNodeModelIndex::Document: { /* We need to intercept and grab the elements of the document node, such * that we preserve/inherit preference applies to them. */ receiver->startDocument(); copyChildren(node, receiver, settings); receiver->endDocument(); break; } default: receiver->item(node); } }
void AccelTreeBuilder<FromDocument>::attribute(const QXmlName &name, const QStringRef &value) { /* Attributes adds a namespace binding, so lets synthesize one. * * We optimize by checking whether we have a namespace for which a binding would * be generated. Happens relatively rarely. */ if(name.hasPrefix()) namespaceBinding(QXmlName(name.namespaceURI(), 0, name.prefix())); m_document->basicData.append(AccelTree::BasicNodeData(currentDepth(), currentParent(), QXmlNodeModelIndex::Attribute, 0, name)); ++m_preNumber; ++m_size.top(); m_isPreviousAtomic = false; if(name.namespaceURI() == StandardNamespaces::xml && name.localName() == StandardLocalNames::id) { const QString normalized(value.toString().simplified()); if(QXmlUtils::isNCName(normalized)) { const QXmlName::LocalNameCode id = m_namePool->allocateLocalName(normalized); const int oldSize = m_document->m_IDs.count(); m_document->m_IDs.insert(id, currentParent()); /* We don't run the value through m_attributeCompress here, because * the likelyhood of it deing identical to another attribute is * very small. */ m_document->data.insert(m_preNumber, normalized); /** * In the case that we're called for doc-available(), m_context is * null, and we need to flag somehow that we failed to load this * document. */ if(oldSize == m_document->m_IDs.count() && m_context) // TODO { Q_ASSERT(m_context); m_context->error(QtXmlPatterns::tr("An %1-attribute with value %2 has already been declared.") .arg(formatKeyword("xml:id"), formatData(normalized)), FromDocument ? ReportContext::FODC0002 : ReportContext::XQDY0091, this); } } else if(m_context) // TODO { Q_ASSERT(m_context); /* If we're building from an XML Document(e.g, we're fed from QXmlStreamReader, we raise FODC0002, * otherwise XQDY0091. */ m_context->error(QtXmlPatterns::tr("An %1-attribute must have a " "valid %2 as value, which %3 isn't.").arg(formatKeyword("xml:id"), formatType(m_namePool, BuiltinTypes::xsNCName), formatData(value.toString())), FromDocument ? ReportContext::FODC0002 : ReportContext::XQDY0091, this); } } else m_document->data.insert(m_preNumber, *m_attributeCompress.insert(value.toString())); }
FunctionSignature::Ptr XSLT20CoreFunctions::retrieveFunctionSignature(const NamePool::Ptr &np, const QXmlName name) { if(StandardNamespaces::fn != name.namespaceURI()) return FunctionSignature::Ptr(); FunctionSignature::Ptr s(functionSignatures().value(name)); if(!s) { /* Alphabetic order. */ if(name.localName() == StandardLocalNames::element_available) { s = addFunction(StandardLocalNames::element_available, 1, 1, CommonSequenceTypes::ExactlyOneBoolean); s->appendArgument(argument(np, "element-name"), CommonSequenceTypes::ExactlyOneString); } else if(name.localName() == StandardLocalNames::function_available) { s = addFunction(StandardLocalNames::function_available, 1, 2, CommonSequenceTypes::ExactlyOneBoolean); s->appendArgument(argument(np, "function_name"), CommonSequenceTypes::ExactlyOneString); s->appendArgument(argument(np, "arity"), CommonSequenceTypes::ExactlyOneInteger); } else if(name.localName() == StandardLocalNames::type_available) { s = addFunction(StandardLocalNames::type_available, 1, 1, CommonSequenceTypes::ExactlyOneBoolean); s->appendArgument(argument(np, "type_name"), CommonSequenceTypes::ExactlyOneString); } else if(name.localName() == StandardLocalNames::system_property) { s = addFunction(StandardLocalNames::system_property, 1, 1, CommonSequenceTypes::ExactlyOneString); s->appendArgument(argument(np, "property_name"), CommonSequenceTypes::ExactlyOneString); } else if(name.localName() == StandardLocalNames::generate_id) { s = addFunction(StandardLocalNames::generate_id, 0, 1, CommonSequenceTypes::ExactlyOneString, Expression::UseContextItem); s->appendArgument(argument(np, "node"), CommonSequenceTypes::ZeroOrOneNode); } else if(name.localName() == StandardLocalNames::unparsed_text) { s = addFunction(StandardLocalNames::unparsed_text, 1, 2, CommonSequenceTypes::ZeroOrOneString, Expression::DisableElimination); s->appendArgument(argument(np, "href"), CommonSequenceTypes::ZeroOrOneString); s->appendArgument(argument(np, "encoding"), CommonSequenceTypes::ExactlyOneString); } else if(name.localName() == StandardLocalNames::unparsed_text_available) { s = addFunction(StandardLocalNames::unparsed_text_available, 1, 2, CommonSequenceTypes::ExactlyOneBoolean, Expression::DisableElimination); s->appendArgument(argument(np, "href"), CommonSequenceTypes::ZeroOrOneString); s->appendArgument(argument(np, "encoding"), CommonSequenceTypes::ZeroOrOneString); } else if(name.localName() == StandardLocalNames::current) { s = addFunction(StandardLocalNames::current, 0, 0, CommonSequenceTypes::ExactlyOneItem, Expression::DisableElimination | Expression::RequiresCurrentItem); } else if(name.localName() == StandardLocalNames::document) { s = addFunction(StandardLocalNames::document, 1, 2, CommonSequenceTypes::OneOrMoreDocumentNodes, Expression::DisableElimination); s->appendArgument(argument(np, "uri-sequence"), CommonSequenceTypes::ZeroOrMoreStrings); s->appendArgument(argument(np, "base-uri-node"), CommonSequenceTypes::ExactlyOneNode); } else if(name.localName() == StandardLocalNames::unparsed_entity_uri) { s = addFunction(StandardLocalNames::unparsed_entity_uri, 1, 1, CommonSequenceTypes::ExactlyOneAnyURI, Expression::RequiresFocus | Expression::DisableElimination); s->appendArgument(argument(np, "entity-name"), CommonSequenceTypes::ExactlyOneString); } else if(name.localName() == StandardLocalNames::unparsed_entity_public_id) { s = addFunction(StandardLocalNames::unparsed_entity_public_id, 1, 1, CommonSequenceTypes::ExactlyOneString, Expression::RequiresFocus | Expression::DisableElimination); s->appendArgument(argument(np, "entity-name"), CommonSequenceTypes::ExactlyOneString); } } return s; }