Пример #1
0
SimXmlElement SimXmlDoc::findElement(const std::string& elementName, const std::string& refId) const
{
  SimXmlElement result(QSharedPointer<QDomElement>(), *this);

  if (isNull()){
    return result;
  }

  QString queryString = simQuery("/SimModel/" + elementName + "[@RefId='" + refId + "'][1]");

  QXmlQuery query;
  QDomNodeModel model(query.namePool(), *(impl()));
  query.setFocus(QXmlItem(model.fromDomNode(impl()->documentElement())));
  query.setQuery(queryString, QUrl(QString::fromStdString(this->path())));

  if (query.isValid()) {

    QXmlResultItems items;

    query.evaluateTo(&items);

    QXmlItem item(items.next());

    if(!item.isNull()) {

      QDomElement elem = model.toDomNode(item.toNodeModelIndex()).toElement();

      QSharedPointer<QDomElement> impl(new QDomElement(elem));

      result = SimXmlElement(impl, *this);
    }
  }

  return result;
}
Пример #2
0
/*!
  Returns the current item. The current item is the last item
  that was produced and returned by next().

  Returns a null QXmlItem if there is no associated QXmlQuery.
 */
QXmlItem QXmlResultItems::current() const
{
    Q_D(const QXmlResultItems);

    if(d->hasError)
        return QXmlItem();
    else
        return d->current;
}
Пример #3
0
/*!
  Returns the next result in the sequence produced by lazy evaluation
  of the associated query. When the returned QXmlItem is null, either
  the evaluation terminated normally without producing another result,
  or an error occurred. Call hasError() to determine whether the null
  item was caused by normal termination or by an error.

  Returns a null QXmlItem if there is no associated QXmlQuery.
 */
QXmlItem QXmlResultItems::next()
{
    Q_D(QXmlResultItems);
    if(d->hasError)
        return QXmlItem();

    try
    {
        d->current = QPatternist::Item::toPublic(d->iterator->next());
        return d->current;
    }
    catch(const QPatternist::Exception)
    {
        d->current = QXmlItem();
        d->hasError = true;
        return QXmlItem();
    }
}
Пример #4
0
bool setFocusHelper(QXmlQuery *const queryInstance,
                    const TInputType &focusValue)
{
    /* We call resourceLoader(), so we have ensured that we have a resourceLoader
     * that we will share in our copy. */
    queryInstance->d->resourceLoader();

    QXmlQuery focusQuery(*queryInstance);

    /* Now we use the same, so we own the loaded document. */
    focusQuery.d->m_resourceLoader = queryInstance->d->m_resourceLoader;

    /* The copy constructor doesn't allow us to copy an existing QXmlQuery and
     * changing the language at the same time so we need to use private API. */
    focusQuery.d->queryLanguage = QXmlQuery::XQuery10;

    Q_ASSERT(focusQuery.queryLanguage() == QXmlQuery::XQuery10);
    focusQuery.bindVariable(QChar::fromLatin1('u'), focusValue);
    focusQuery.setQuery(QLatin1String("doc($u)"));
    Q_ASSERT(focusQuery.isValid());

    QXmlResultItems focusResult;

    queryInstance->d->m_resourceLoader = focusQuery.d->m_resourceLoader;

    focusQuery.evaluateTo(&focusResult);
    const QXmlItem focusItem(focusResult.next());

    if(focusItem.isNull() || focusResult.hasError())
    {
        /* The previous focus must be cleared in error situations.
         * Otherwise the query may be left in an inconsistent state. */
        queryInstance->setFocus(QXmlItem());
        return false;
    }
    else
    {
        queryInstance->setFocus(focusItem);
        return true;
    }
}
Пример #5
0
std::vector<SimXmlElement> SimXmlDoc::getElements(const std::string& elementName) const
{
  std::vector<SimXmlElement> result;

  if (isNull()){
    return result;
  }

  QString queryString = simQuery("/SimModel/" + elementName);

  QXmlQuery query;
  QDomNodeModel model(query.namePool(), *(impl()));
  query.setFocus(QXmlItem(model.fromDomNode(impl()->documentElement())));
  query.setQuery(queryString, QUrl(QString::fromStdString(this->path())));

  if (query.isValid()) {

    QString junk;

    QXmlResultItems items;

    query.evaluateTo(&items);

    QXmlItem item(items.next());

    while (!item.isNull()) {

      QDomElement elem = model.toDomNode(item.toNodeModelIndex()).toElement();

      QSharedPointer<QDomElement> impl(new QDomElement(elem));

      result.push_back(SimXmlElement(impl, *this));

      // get next item
      item = items.next();
    }
  }

  return result;
}
Пример #6
0
void tst_QXmlItem::defaultConstructor() const
{
    {
        QXmlItem();
    }

    {
        QXmlItem();
        QXmlItem();
    }

    {
        QXmlItem();
        QXmlItem();
        QXmlItem();
    }
}
Пример #7
0
int main(int argc, char **argv)
{
    enum ExitCode
    {
        /**
         * We start from 2, because QApplicationArgumentParser
         * uses 1.
         */
        QueryFailure = 2,
        StdOutFailure
    };

    const QCoreApplication app(argc, argv);
    QCoreApplication::setApplicationName(QLatin1String("xmlpatterns"));

    QXmlNamePool namePool;
    PatternistApplicationParser parser(argc, argv, namePool);
    parser.setApplicationDescription(QLatin1String("A tool for running XQuery queries."));
    parser.setApplicationVersion(QLatin1String("0.1"));

    QApplicationArgument param(QLatin1String("param"),
                               QXmlPatternistCLI::tr("Binds an external variable. The value is directly available using the variable reference: $name."),
                               qMetaTypeId<Parameter>());
    param.setMaximumOccurrence(-1);
    parser.addArgument(param);

    const QApplicationArgument noformat(QLatin1String("no-format"),
                                        QXmlPatternistCLI::tr("By default output is formatted for readability. When specified, strict serialization is performed."));
    parser.addArgument(noformat);

    const QApplicationArgument isURI(QLatin1String("is-uri"),
                                     QXmlPatternistCLI::tr("If specified, all filenames on the command line are interpreted as URIs instead of a local filenames."));
    parser.addArgument(isURI);

    const QApplicationArgument initialTemplateName(QLatin1String("initial-template"),
                                                   QXmlPatternistCLI::tr("The name of the initial template to call as a Clark Name."),
                                                   QVariant::String);
    parser.addArgument(initialTemplateName);

    /* The temporary object is required to compile with g++ 3.3. */
    QApplicationArgument queryURI = QApplicationArgument(QLatin1String("query/stylesheet"),
                                                         QXmlPatternistCLI::tr("A local filename pointing to the query to run. If the name ends with .xsl it's assumed "
                                                                               "to be an XSL-T stylesheet. If it ends with .xq, it's assumed to be an XQuery query. (In "
                                                                               "other cases it's also assumed to be an XQuery query, but that interpretation may "
                                                                               "change in a future release of Qt.)"),
                                                         QVariant::String);
    queryURI.setMinimumOccurrence(1);
    queryURI.setNameless(true);
    parser.addArgument(queryURI);

    QApplicationArgument focus = QApplicationArgument(QLatin1String("focus"),
                                                      QXmlPatternistCLI::tr("The document to use as focus. Mandatory "
                                                                            "in case a stylesheet is used. This option is "
                                                                            "also affected by the is-uris option."),
                                                      QVariant::String);
    focus.setMinimumOccurrence(0);
    focus.setNameless(true);
    parser.addArgument(focus);

    QApplicationArgument output(QLatin1String("output"),
                                QXmlPatternistCLI::tr("A local file to which the output should be written. "
                                                      "The file is overwritten, or if not exist, created. "
                                                      "If absent, stdout is used."),
                                qMetaTypeId<QIODevice *>());
    parser.addArgument(output);

    if(!parser.parse())
        return parser.exitCode();

    /* Get the query URI. */
    const QUrl effectiveURI(finalizeURI(parser, isURI, queryURI));

    QXmlQuery::QueryLanguage lang;

    if(effectiveURI.toString().endsWith(QLatin1String(".xsl")))
         lang = QXmlQuery::XSLT20;
    else
         lang = QXmlQuery::XQuery10;

    if(lang == QXmlQuery::XQuery10 && parser.has(initialTemplateName))
    {
        parser.message(QXmlPatternistCLI::tr("An initial template name cannot be specified when running an XQuery."));
        return QApplicationArgumentParser::ParseError;
    }

    QXmlQuery query(lang, namePool);

    query.setInitialTemplateName(qvariant_cast<QXmlName>(parser.value(initialTemplateName)));

    /* Bind external variables. */
    {
        const QVariantList parameters(parser.values(param));
        const int len = parameters.count();

        /* For tracking duplicates. */
        QSet<QString> usedParameters;

        for(int i = 0; i < len; ++i)
        {
            const Parameter p(qvariant_cast<Parameter>(parameters.at(i)));

            if(usedParameters.contains(p.first))
            {
                parser.message(QXmlPatternistCLI::tr("Each parameter must be unique, %1 is specified at least twice.").arg(p.first));
                return QApplicationArgumentParser::ParseError;
            }
            else
            {
                usedParameters.insert(p.first);
                query.bindVariable(p.first, QXmlItem(p.second));
            }
        }
    }

    if(parser.has(focus))
    {
        if(!query.setFocus(finalizeURI(parser, isURI, focus)))
            return QueryFailure;
    }
    else if(lang == QXmlQuery::XSLT20 && !parser.has(initialTemplateName))
    {
        parser.message(QXmlPatternistCLI::tr("When a stylesheet is used, a "
                                             "document must be specified as a focus, or an "
                                             "initial template name must be specified, or both."));
        return QApplicationArgumentParser::ParseError;
    }

    query.setQuery(effectiveURI);

    const QPatternist::AutoPtr<QIODevice> outDevice(qvariant_cast<QIODevice *>(parser.value(output)));
    Q_ASSERT(outDevice);
    Q_ASSERT(outDevice->isWritable());

    if(query.isValid())
    {
        typedef QPatternist::AutoPtr<QAbstractXmlReceiver> RecPtr;
        RecPtr receiver;

        if(parser.has(noformat))
            receiver = RecPtr(new QXmlSerializer(query, outDevice.data()));
        else
            receiver = RecPtr(new QXmlFormatter(query, outDevice.data()));

        const bool success = query.evaluateTo(receiver.data());

        if(success)
            return parser.exitCode();
        else
            return QueryFailure;
    }
    else
        return QueryFailure;
}
Пример #8
0
bool XSLTProcessor::transformToString(Node* sourceNode, String&, String& resultString, String&)
{
    bool success = false;

    RefPtr<XSLStyleSheet> stylesheet = m_stylesheet;
    if (!stylesheet && m_stylesheetRootNode) {
        Node* node = m_stylesheetRootNode.get();
        stylesheet = XSLStyleSheet::createForXSLTProcessor(node->parent() ? node->parent() : node,
            node->document()->url().string(),
            node->document()->url()); // FIXME: Should we use baseURL here?

        // According to Mozilla documentation, the node must be a Document node, an xsl:stylesheet or xsl:transform element.
        // But we just use text content regardless of node type.
        stylesheet->parseString(createMarkup(node));
    }

    if (!stylesheet || stylesheet->sheetString().isEmpty())
        return success;

    RefPtr<Document> ownerDocument = sourceNode->document();
    bool sourceIsDocument = (sourceNode == ownerDocument.get());

    QXmlQuery query(QXmlQuery::XSLT20);

    XSLTMessageHandler messageHandler(ownerDocument.get());
    XSLTUriResolver uriResolver(ownerDocument.get());
    query.setMessageHandler(&messageHandler);

    XSLTProcessor::ParameterMap::iterator end = m_parameters.end();
    for (XSLTProcessor::ParameterMap::iterator it = m_parameters.begin(); it != end; ++it)
        query.bindVariable(QString(it->first), QXmlItem(QVariant(it->second)));

    QString source;
    if (sourceIsDocument && ownerDocument->transformSource())
        source = ownerDocument->transformSource()->platformSource();
    if (!sourceIsDocument || source.isEmpty())
        source = createMarkup(sourceNode);

    QBuffer inputBuffer;
    QBuffer styleSheetBuffer;
    QBuffer outputBuffer;

    inputBuffer.setData(source.toUtf8());
    styleSheetBuffer.setData(QString(stylesheet->sheetString()).toUtf8());

    inputBuffer.open(QIODevice::ReadOnly);
    styleSheetBuffer.open(QIODevice::ReadOnly);
    outputBuffer.open(QIODevice::ReadWrite);

    query.setFocus(&inputBuffer);
    query.setQuery(&styleSheetBuffer, QUrl(stylesheet->href()));

    query.setUriResolver(&uriResolver);

    success = query.evaluateTo(&outputBuffer);
    outputBuffer.reset();
    resultString = QString::fromUtf8(outputBuffer.readAll()).trimmed();

    if (m_stylesheet) {
        m_stylesheet->clearDocuments();
        m_stylesheet = 0;
    }

    return success;
}
Пример #9
0
int main(int argc, char **argv)
{
    enum ExitCode
    {
        /**
         * We start from 2, because QApplicationArgumentParser
         * uses 1.
         */
        QueryFailure = 2,
        StdOutFailure
    };

    const QCoreApplication app(argc, argv);
    QCoreApplication::setApplicationName(QLatin1String("xmlpatterns"));

    PatternistApplicationParser parser(argc, argv);
    parser.setApplicationDescription(QLatin1String("A tool for running XQuery queries."));
    parser.setApplicationVersion(QLatin1String("0.1"));

    /* Is there a better way to do this? Probably not, but if the class becomes public, we probably
     * want a helper function that wraps this hack. */
    const int parameterType = qVariantFromValue(Parameter()).userType();
    const int outputType = qVariantFromValue(static_cast<QIODevice *>(0)).userType();

    QApplicationArgument param(QLatin1String("param"),
                               QXmlPatternistCLI::tr("Binds an external variable. The value is directly available using the variable reference: $name."),
                               parameterType);
    param.setMaximumOccurrence(-1);
    parser.addArgument(param);

    const QApplicationArgument noformat(QLatin1String("no-format"),
                                        QXmlPatternistCLI::tr("By default output is formatted for readability. When specified, strict serialization is performed."));
    parser.addArgument(noformat);

    const QApplicationArgument isURI(QLatin1String("is-uri"),
                                     QXmlPatternistCLI::tr("If specified, the filename is interpreted as a URI instead of a local filename."));
    parser.addArgument(isURI);

    /* The temporary object is required to compile with g++ 3.3. */
    QApplicationArgument queryURI = QApplicationArgument(QString(), /* Nameless. */
                                                         QXmlPatternistCLI::tr("A local filename pointing to the query to run. "
                                                                               "If the name ends with .xq it's assumed "
                                                                               "to be an XQuery query. (In other cases too, but "
                                                                               "that interpretation may change in a future release of Qt.)"),
                                  QVariant::String);
    queryURI.setMinimumOccurrence(1);
    parser.addArgument(queryURI);

    QApplicationArgument output(QLatin1String("output"),
                                QXmlPatternistCLI::tr("A local file to which the output should be written. The file is overwritten, or if not exist, created. If absent, stdout is used."),
                                outputType);
    parser.addArgument(output);

    if(!parser.parse())
        return parser.exitCode();

    QXmlQuery query;

    /* Bind external variables. */
    {
        const QVariantList parameters(parser.values(param));
        const int len = parameters.count();

        for(int i = 0; i < len; ++i)
        {
            const Parameter p(qVariantValue<Parameter>(parameters.at(i)));
            query.bindVariable(p.first, QXmlItem(p.second));
        }
    }

    /* The final preparations and execute the query. */
    QPatternist::ColoringMessageHandler messageHandler;
    query.setMessageHandler(&messageHandler);

    /* Get the query URI. */
    QUrl userURI;
    {
        const QString stringURI(parser.value(queryURI).toString());

        if(parser.has(isURI))
            userURI = QUrl::fromEncoded(stringURI.toLatin1());
        else
            userURI = QUrl::fromLocalFile(stringURI);
    }
    const QUrl effectiveURI(QUrl::fromLocalFile(QDir::current().absolutePath() + QLatin1Char('/')).resolved(userURI));

    Q_ASSERT_X(userURI.isValid(), Q_FUNC_INFO,
               "QApplicationArgumentParser should promise us this.");

    query.setQuery(effectiveURI);

    QIODevice *const outDevice = qVariantValue<QIODevice *>(parser.value(output));
    Q_ASSERT(outDevice);
    Q_ASSERT(outDevice->isWritable());

    if(query.isValid())
    {
        QAbstractXmlReceiver *receiver = 0;

        if(parser.has(noformat))
            receiver = new QXmlSerializer(query, outDevice);
        else
            receiver = new QXmlFormatter(query, outDevice);

        const bool success = query.evaluateTo(receiver);
        delete outDevice;
        delete receiver;

        if(success)
            return parser.exitCode();
        else
            return QueryFailure;
    }
    else
    {
        delete outDevice;
        return QueryFailure;
    }
}