QString FunctionSignature::displayName(const NamePool::Ptr &np) const { QString result; result += np->displayName(name()); result += QLatin1Char('('); FunctionArgument::List::const_iterator it(m_arguments.constBegin()); const FunctionArgument::List::const_iterator end(m_arguments.constEnd()); if(it != end) { while(true) { result += QLatin1Char('$'); result += np->displayName((*it)->name()); result += QLatin1String(" as "); result += (*it)->type()->displayName(np); ++it; if(it == end) break; result += QLatin1String(", "); } } if(m_maxArgs == FunctionSignature::UnlimitedArity) result += QLatin1String(", ..."); result += QLatin1String(") as "); result += m_returnType->displayName(np); return result; }
/** * 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); }
void AccelTree::printStats(const NamePool::Ptr &np) const { Q_ASSERT(np); #ifdef QT_NO_DEBUG Q_UNUSED(np); /* Needed when compiling in release mode. */ #else const int len = basicData.count(); pDebug() << "AccelTree stats for" << (m_documentURI.isEmpty() ? QString::fromLatin1("<empty URI>") : m_documentURI.toString()); pDebug() << "Maximum pre number:" << maximumPreNumber(); pDebug() << "+---------------+-------+-------+---------------+-------+--------------+-------+"; pDebug() << "| Pre number | Depth | Size | Post Number | Kind | Name | Value |"; pDebug() << "+---------------+-------+-------+---------------+-------+--------------+-------+"; for(int i = 0; i < len; ++i) { const BasicNodeData &v = basicData.at(i); pDebug() << '|' << i << "\t\t|" << v.depth() << "\t|" << v.size() << "\t|" << postNumber(i) << "\t|" << v.kind() << "\t\t|" << (v.name().isNull() ? QString::fromLatin1("(none)") : np->displayName(v.name())) << "\t\t|" << ((v.kind() == QXmlNodeModelIndex::Text && isCompressed(i)) ? CompressedWhitespace::decompress(data.value(i)) : data.value(i)) << "\t|"; /* pDebug() << '|' << QString().arg(i, 14) << '|' << QString().arg(v.depth(), 6) << '|' << QString().arg(v.size(), 6) << '|' << QString().arg(postNumber(i), 14) << '|' << QString().arg(v.kind(), 6) << '|'; */ } pDebug() << "+---------------+-------+-------+---------------+-------+--------------+"; pDebug() << "Namespaces(" << namespaces.count() << "):"; QHashIterator<PreNumber, QVector<QXmlName> > it(namespaces); while(it.hasNext()) { it.next(); pDebug() << "PreNumber: " << QString::number(it.key()); for(int i = 0; i < it.value().count(); ++i) pDebug() << "\t\t" << np->stringForPrefix(it.value().at(i).prefix()) << " = " << np->stringForNamespace(it.value().at(i).namespaceURI()); } #endif }
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); }
QString LocalNameTest::displayName(const NamePool::Ptr &np) const { QString displayOther(m_primaryType->displayName(np)); return displayOther.insert(displayOther.size() - 1, QString::fromLatin1("*:") + np->stringForLocalName(m_ncName)); }
bool AccelTreeResourceLoader::streamToReceiver(QIODevice *const dev, AccelTreeBuilder<true> *const receiver, const NamePool::Ptr &np, const ReportContext::Ptr &context, const QUrl &uri) { Q_ASSERT(dev); Q_ASSERT(receiver); Q_ASSERT(np); QXmlStreamReader reader(dev); /* Optimize: change NamePool to take QStringRef such that we don't have to call toString() below. That * will save us a gazillion of temporary QStrings. */ while(!reader.atEnd()) { reader.readNext(); switch(reader.tokenType()) { case QXmlStreamReader::StartElement: { /* Send the name. */ receiver->startElement(np->allocateQName(reader.namespaceUri().toString(), reader.name().toString(), reader.prefix().toString()), reader.lineNumber(), reader.columnNumber()); /* Send namespace declarations. */ const QXmlStreamNamespaceDeclarations &nss = reader.namespaceDeclarations(); /* The far most common case, is for it to be empty. */ if(!nss.isEmpty()) { const int len = nss.size(); for(int i = 0; i < len; ++i) { const QXmlStreamNamespaceDeclaration &ns = nss.at(i); receiver->namespaceBinding(np->allocateBinding(ns.prefix().toString(), ns.namespaceUri().toString())); } } /* Send attributes. */ const QXmlStreamAttributes &attrs = reader.attributes(); const int len = attrs.size(); for(int i = 0; i < len; ++i) { const QXmlStreamAttribute &attr = attrs.at(i); receiver->attribute(np->allocateQName(attr.namespaceUri().toString(), attr.name().toString(), attr.prefix().toString()), attr.value()); } continue; } case QXmlStreamReader::EndElement: { receiver->endElement(); continue; } case QXmlStreamReader::Characters: { if(reader.isWhitespace()) receiver->whitespaceOnly(reader.text()); else receiver->characters(reader.text()); continue; } case QXmlStreamReader::Comment: { receiver->comment(reader.text().toString()); continue; } case QXmlStreamReader::ProcessingInstruction: { receiver->processingInstruction(np->allocateQName(QString(), reader.processingInstructionTarget().toString()), reader.processingInstructionData().toString()); continue; } case QXmlStreamReader::StartDocument: { receiver->startDocument(); continue; } case QXmlStreamReader::EndDocument: { receiver->endDocument(); continue; } case QXmlStreamReader::EntityReference: /* Fallthrough. */ case QXmlStreamReader::DTD: { /* We just ignore any DTD and entity references. */ continue; } case QXmlStreamReader::Invalid: { if(context) context->error(escape(reader.errorString()), ReportContext::FODC0002, QSourceLocation(uri, reader.lineNumber(), reader.columnNumber())); return false; } case QXmlStreamReader::NoToken: { Q_ASSERT_X(false, Q_FUNC_INFO, "This token is never expected to be received."); return false; } } } return true; }
QString AnySimpleType::displayName(const NamePool::Ptr &np) const { return np->displayName(name(np)); }
QXmlName AnySimpleType::name(const NamePool::Ptr &np) const { return np->allocateQName(StandardNamespaces::xs, QLatin1String("anySimpleType")); }
QString NamedSchemaComponent::displayName(const NamePool::Ptr &np) const { return np->displayName(m_name); }
QString QNameTest::displayName(const NamePool::Ptr &np) const { QString displayOther(m_primaryType->displayName(np)); return displayOther.insert(displayOther.size() - 1, np->displayName(m_qName)); }
QString NamespaceNameTest::displayName(const NamePool::Ptr &np) const { return QLatin1Char('{') + np->stringForNamespace(m_namespaceURI) + QLatin1String("}:*"); }
/** * 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; }
QString XsdComplexType::displayName(const NamePool::Ptr &np) const { return np->displayName(name(np)); }
QXmlName Untyped::name(const NamePool::Ptr &np) const { return np->allocateQName(StandardNamespaces::xs, QLatin1String("untyped")); }