Question

I'm trying to parse Mac application's "Info.plist" with QXmlQuery in order to retrieve version number. Here's an example on Info.plist:

<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>13A598</string>

    <key>CFBundleShortVersionString</key>
<string>1.4</string>

    <key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.4</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

The aim is to get the "1.4" value using "CFBundleShortVersionString" key. To do so, I use the following query:

/plist/dict/key[node()='CFBundleShortVersionString']/following-sibling::string[1]/node()

It works perfectly.

Now, when I transpose this to Qt, I use the following code:

QString version;
QString fileName = appPath + "/Contents/Info.plist";
QFile file(fileName);
if (file.open(QIODevice::ReadOnly)) {
    QXmlQuery query;
    query.bindVariable("file", &file);
    query.setQuery("declare variable $file external; doc($file)/plist/dict/key[node()='CFBundleShortVersionString']/following-sibling::string[1]/node()");
    query.evaluateTo(&version);
}
return version;

It goes fine until "query.evaluateTo", which stucks for a while, then gives me an empty value in "version".

Can someone help?

Was it helpful?

Solution 2

Thanks a lot for your reply. However and after lots of investigations, here's the thing.

My code has no problem. It's a bug from Qt5.1 branch. QXmlQuery needs a QCoreApplication to work, that's why your code works fine. But when used with QApplication, evaluateTo fails.

If I try your code as-is, it works. If I change from QCoreApplication to QApplication, it fails.

I wrote a bug report on Qt's JIRA.

OTHER TIPS

I can't reproduce. The below works under both Qt 4.8.5 and 5.1.1 under OS X.

Output:

true "1.4
" 

Apparently, the version string contains a newline at the end. Who knows why.

#include <QXmlQuery>
#include <QBuffer>
#include <QTextStream>
#include <QCoreApplication>
#include <QDebug>

const char xmlData[]=
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<plist version=\"1.0\"><dict>"
        "<key>BuildMachineOSBuild</key><string>13A598</string>"
        "<key>CFBundleShortVersionString</key><string>1.4</string>"
        "<key>CFBundleSignature</key><string>????</string>"
        "<key>CFBundleVersion</key><string>1.4</string>"
        "<key>NSPrincipalClass</key><string>NSApplication</string>"
        "</dict></plist>";

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QTextStream out(stdout);
    QByteArray data(QByteArray::fromRawData(xmlData, sizeof(xmlData)-1));
    QBuffer buffer(&data);
    if (buffer.open(QIODevice::ReadOnly)) {
        QString version;
        QXmlQuery query;
        query.bindVariable("file", &buffer);
        query.setQuery("declare variable $file external; doc($file)/plist/dict/key[node()='CFBundleShortVersionString']/following-sibling::string[1]/node()");
        bool rc = query.evaluateTo(&version);
        qDebug() << rc << version;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top