Why QXmlQuery seem to add a ` \n` to results? (and how to solve it?)

Viewed 180

Writing a little code to extract some values from an XML, the result of the XPath seem to add \n after the content.

#include <QCoreApplication>
#include <QXmlQuery>
#include <QString>
#include <QDebug>

auto main(int argn, char* argc[])->int
{
    QCoreApplication app(argn, argc);

    QString replyContent="<Root isOk='ok'/>";

    QXmlQuery query;
    query.setFocus(replyContent);
    query.setQuery("string(//@isOk)");

    // Attribute seem to add \n
    QString queryResult;    
    if (query.evaluateTo(&queryResult))
    {
        qDebug() << queryResult;              // Where this \n come from?
        qDebug() << queryResult.size();       // Why 3? shouldn't be 2?
    }
}

Expected result:

"ok"
2

Given result:

"ok\n"
3

This obviously has some side effects which I would like to avoid.

Why is this \n added? And how to solve it?

2 Answers

I think that this is introduced by the QXmlFormatter that is used when serialising the results to a QString; I suspect that QXmlFormatter::endDocument writes a newline.

One workaround would be to output to a string list instead, then pick the first element:

QStringList results;
if (query.evaluateTo(&results))
{
    const QString& queryResult = results.first();
    qDebug() << queryResult;
    qDebug() << queryResult.size();
}

You might choose to join() the results instead, if you need them all.

Alternatively you can take full control of the serialization and use either QXmlSerializer or QXmlFormatter. That way you will have in the output whatever you ask, not some defaults you are provided with. It will have more code, that's true but the intent will be clearer than just discarding some newline at the end.

Here is an example of how to do it with QXmlSerializer (which produces no redundant symbols by default):

#include <QCoreApplication>
#include <QXmlQuery>
#include <QXmlSerializer>
#include <QString>
#include <QBuffer>
#include <QDebug>

auto main(int argn, char* argc[])->int
{
    QCoreApplication app(argn, argc);

    QString replyContent="<Root isOk='ok'/>";

    QXmlQuery query;
    query.setFocus(replyContent);
    query.setQuery("string(//@isOk)");

    QBuffer buffer;
    buffer.open(QBuffer::ReadWrite);
    QXmlSerializer serializer(query, &buffer);
    if (query.evaluateTo(&serializer))
    {
        QString queryResult = QString::fromUtf8(buffer.buffer());
        qDebug() << queryResult;
        qDebug() << queryResult.size();
    }
}
Related