/*!
  \reimp
 */
void QXmlSerializer::startElement(const QXmlName &name)
{
    Q_D(QXmlSerializer);
    Q_ASSERT(d->device);
    Q_ASSERT(d->device->isWritable());
    Q_ASSERT(d->codec);
    Q_ASSERT(!name.isNull());

    d->namespaces.push(QVector<QXmlName>());

    if(atDocumentRoot())
    {
        if(d->state == BeforeDocumentElement)
            d->state = InsideDocumentElement;
        else if(d->state != InsideDocumentElement)
        {
            d->query.d->staticContext()->error(QtXmlPatterns::tr(
               "Element %1 can't be serialized because it appears outside "
               "the document element.").arg(formatKeyword(d->np, name)),
                                               ReportContext::SENR0001,
                                               d->query.d->expression().data());
        }
    }

    startContent();
    d->write('<');
    write(name);

    /* Ensure that the namespace URI used in the name gets outputted. */
    namespaceBinding(name);

    d->hasClosedElement.push(qMakePair(name, false));
    d->isPreviousAtomic = false;
}
/*!
  \reimp
 */
void QXmlSerializer::attribute(const QXmlName &name,
                               const QStringRef &value)
{
    Q_D(QXmlSerializer);
    Q_ASSERT(!name.isNull());

    /* Ensure that the namespace URI used in the name gets outputted. */
    {
        /* Since attributes doesn't pick up the default namespace, a
         * namespace declaration would cause trouble if we output it. */
        if(name.prefix() != StandardPrefixes::empty)
            namespaceBinding(name);
    }

    if(atDocumentRoot())
    {
        Q_UNUSED(d);
        d->query.d->staticContext()->error(QtXmlPatterns::tr(
           "Attribute %1 can't be serialized because it appears at "
           "the top level.").arg(formatKeyword(d->np, name)),
                                           ReportContext::SENR0001,
                                           d->query.d->expression().data());
    }
    else
    {
        d->write(' ');
        write(name);
        write("=\"");
        writeEscapedAttribute(value.toString());
        d->write('"');
    }
}
Beispiel #3
0
FunctionArgument::FunctionArgument(const QXmlName nameP,
                                   const SequenceType::Ptr &typeP) : m_name(nameP),
                                                                     m_type(typeP)
{
    Q_ASSERT(!nameP.isNull());
    Q_ASSERT(typeP);
}
Beispiel #4
0
ItemType::Ptr QNameTest::create(const ItemType::Ptr &primaryType, const QXmlName qName)
{
    Q_ASSERT(!qName.isNull());
    Q_ASSERT(primaryType);

    return ItemType::Ptr(new QNameTest(primaryType, qName));
}
Beispiel #5
0
/*!
  Check that functions have the correct const qualification.
 */
void tst_QXmlName::constCorrectness() const
{
    const QXmlName name;

    /* isNull() */
    QVERIFY(name.isNull());

    /* operator==() */
    QVERIFY(name == name);

    /* operator!=() */
    QVERIFY(!(name != name));

    QXmlNamePool namePool;
    const QXmlName name2(namePool, QLatin1String("localName"), QLatin1String("http://example.com/"), QLatin1String("prefix"));

    /* namespaceUri(). */
    QCOMPARE(name2.namespaceUri(namePool), QLatin1String("http://example.com/"));

    /* localName(). */
    QCOMPARE(name2.localName(namePool), QLatin1String("localName"));

    /* prefix(). */
    QCOMPARE(name2.prefix(namePool), QLatin1String("prefix"));

    /* toClarkname(). */
    QCOMPARE(name2.toClarkName(namePool), QLatin1String("{http://example.com/}prefix:localName"));
}
QPatternist::Item
ExternalSourceLoader::evaluateSingleton(const QXmlName name,
                                        const QPatternist::DynamicContext::Ptr &context)
{
    Q_ASSERT(!name.isNull());
    const VariableValue variable(m_variableMap.value(Global::namePool()->stringForLocalName(name.localName())));

    if(variable.second == Document)
    {
        Q_ASSERT_X(QFile::exists(variable.first.toLocalFile()), Q_FUNC_INFO,
                   qPrintable(QString::fromLatin1("The file %1 doesn't exist").arg(variable.first.toLocalFile())));
        Q_ASSERT_X(m_resourceLoader->openDocument(variable.first, context), Q_FUNC_INFO,
                   "We're supposed to have the value. If not, an error should have been issued at query compile time.");

        return m_resourceLoader->openDocument(variable.first, context);
    }
    else if(variable.second == Query)
    {
        /* Well, here we open the file and execute it. */
        m_query.setQuery(QUrl::fromLocalFile(variable.first.toLocalFile()));
        Q_ASSERT(m_query.isValid());

        QXmlResultItems result;
        m_query.evaluateTo(&result);

        return QPatternist::Item::fromPublic(result.next());
    }
    else
    {
        Q_ASSERT(variable.second == URI);
        return QPatternist::AtomicString::fromValue(variable.first.toString());
    }
}
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));
}
SequenceType::Ptr ExternalVariableLoader::announceExternalVariable(const QXmlName name,
                                                                   const SequenceType::Ptr &declaredType)
{
    Q_ASSERT(!name.isNull());
    Q_ASSERT(declaredType);
    Q_UNUSED(name); /* Needed when compiling in release mode. */
    Q_UNUSED(declaredType); /* Needed when compiling in release mode. */

    return SequenceType::Ptr();
}
Item::Iterator::Ptr ExternalVariableLoader::evaluateSequence(const QXmlName name,
                                                             const DynamicContext::Ptr &context)
{
    Q_ASSERT(!name.isNull());
    const Item item(evaluateSingleton(name, context));

    if(item)
        return makeSingletonIterator(item);
    else
        return CommonValues::emptyIterator;
}
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();
}
Beispiel #11
0
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;
}
Beispiel #12
0
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;
}
Beispiel #13
0
/*!
  Binds the variable \a name to the \a value so that $\a name can be
  used from within the query to refer to the \a value.

  \a name must not be \e null. \a {name}.isNull() must return false.
  If \a name has already been bound by a previous bindVariable() call,
  its previous binding will be overridden.

  If \a {value} is null so that \a {value}.isNull() returns true, and
  \a {name} already has a binding, the effect is to remove the
  existing binding for \a {name}.

  To bind a value of type QString or QUrl, wrap the value in a
  QVariant such that QXmlItem's QVariant constructor is called.

  All strings processed by the query must be valid XQuery strings,
  which means they must contain only XML 1.0 characters. However,
  this requirement is not checked. If the query processes an invalid
  string, the behavior is undefined.

  \sa QVariant::isValid(), {QtXDM}{How QVariant maps to XQuery's Data Model},
   QXmlItem::isNull()
 */
void QXmlQuery::bindVariable(const QXmlName &name, const QXmlItem &value)
{
    if(name.isNull())
    {
        qWarning("The variable name cannot be null.");
        return;
    }

    const QPatternist::VariableLoader::Ptr vl(d->variableLoader());
    const QVariant variant(QVariant::fromValue(value));

    /* If the type of the variable changed(as opposed to only the value),
     * we will have to recompile. */
    if(vl->invalidationRequired(name, variant) || value.isNull())
        d->recompileRequired();

    vl->addBinding(name, variant);
}
Beispiel #14
0
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());
    }
}
Beispiel #15
0
/*!
 \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('"');
}
Beispiel #16
0
/*!
  Binds the variable \a name to the \a device so that $\a name can be
  used from within the query to refer to the \a device. The QIODevice
  \a device is exposed to the query as a URI of type \c{xs:anyURI},
  which can be passed to the \c{fn:doc()} function to be read. E.g.,
  this function can be used to pass an XML document in memory to
  \c{fn:doc}.

  \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 1

  The caller must ensure that \a device has been opened with at least
  QIODevice::ReadOnly prior to this binding. Otherwise, behavior is
  undefined.

  If the query will access an XML document contained in a QString, use
  a QBuffer as shown in the following snippet. Suppose \e myQString
  contains \c{<document>content</document>}

  \snippet doc/src/snippets/qxmlquery/bindingExample.cpp 0

  \a name must not be \e null. \a {name}.isNull() must return false.
  If \a name has already been bound, its previous binding will be
  overridden. The URI that \a name evaluates to is arbitrary and may
  change.

  If the type of the variable binding changes (e.g., if a previous
  binding by the same name was a QVariant, or if there was no previous
  binding), isValid() will return \c{false}, and recompilation of the
  query text is required. To recompile the query, call setQuery(). For
  this reason, bindVariable() should be called before setQuery(), if
  possible.

  \note \a device must not be deleted while this QXmlQuery exists.
*/
void QXmlQuery::bindVariable(const QXmlName &name, QIODevice *device)
{
    if(device && !device->isReadable())
    {
        qWarning("A null, or readable QIODevice must be passed.");
        return;
    }

    if(name.isNull())
    {
        qWarning("The variable name cannot be null.");
        return;
    }

    const QPatternist::VariableLoader::Ptr vl(d->variableLoader());

    if(device)
    {
        const QVariant variant(QVariant::fromValue(device));

        if(vl->invalidationRequired(name, variant))
            d->recompileRequired();

        vl->addBinding(name, variant);

        /* We need to tell the resource loader to discard its document, because
         * the underlying QIODevice has changed, but the variable name is the
         * same which means that the URI is the same, and hence the resource
         * loader will return the document for the old QIODevice.
         */
        d->resourceLoader()->clear(QUrl(QLatin1String("tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:") + d->namePool.d->stringForLocalName(name.localName())));
    }
    else
    {
        vl->removeBinding(name);
        d->recompileRequired();
    }
}
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();
}
Beispiel #18
0
QNameValue::Ptr QNameValue::fromValue(const NamePool::Ptr &np, const QXmlName name)
{
    Q_ASSERT(!name.isNull());
    return QNameValue::Ptr(new QNameValue(np, name));
}
Beispiel #19
0
void tst_QXmlName::isNull() const
{
    /* Check default value. */
    QXmlName name;
    QVERIFY(name.isNull());
}
Item ExternalVariableLoader::evaluateSingleton(const QXmlName name,
                                                    const DynamicContext::Ptr &context)
{
    Q_ASSERT(!name.isNull());
    return Boolean::fromValue(evaluateEBV(name, context));
}
Beispiel #21
0
QNameTest::QNameTest(const ItemType::Ptr &primaryType,
                     const QXmlName qName) : AbstractNodeTest(primaryType)
                                        , m_qName(qName)
{
    Q_ASSERT(!qName.isNull());
}
bool ExternalVariableLoader::evaluateEBV(const QXmlName name,
                                         const DynamicContext::Ptr &context)
{
    Q_ASSERT(!name.isNull());
    return Boolean::evaluateEBV(evaluateSequence(name, context), context);
}
Beispiel #23
0
QNameValue::QNameValue(const NamePool::Ptr &np, const QXmlName name) : m_qName(name)
    , m_namePool(np)
{
    Q_ASSERT(!name.isNull());
    Q_ASSERT(m_namePool);
}