QXmlItem an XQuery binden?

Alles rund um die Programmierung mit Qt
Antworten
reimer
Beiträge: 14
Registriert: 27. Juni 2008 19:21

QXmlItem an XQuery binden?

Beitrag von reimer »

Ich versuche iterativ die filter Attribute der rule-Tags aus folgender XML-Datei auszulesen:

artifacts.xml

Code: Alles auswählen

<?xml version='1.0' encoding='UTF-8'?>
<?artifactRepository version='1.1.0'?>
<repository name='AppWrench' type='org.eclipse.equinox.p2.artifact.repository.simpleRepository' version='1'>
  <properties size='2'>
    <property name='p2.timestamp' value='1337880100226'/>
    <property name='p2.compressed' value='true'/>
  </properties>
  <mappings size='3'>
    <rule filter='(& (classifier=osgi.bundle))' output='${repoUrl}/plugins/${id}_${version}.jar'/>
    <rule filter='(& (classifier=binary))' output='${repoUrl}/binary/${id}_${version}'/>
    <rule filter='(& (classifier=org.eclipse.update.feature))' output='${repoUrl}/features/${id}_${version}.jar'/>
  </mappings>
</repository>
Um's einfach zu halten, fetche ich zunaechst die Rules und verarbeite die erste Rule hardcodiert weiter. In Zeile 60 nehme ich die erste Rule als Basis fuer einen neuen XQuery und binde die an die ruleNode Variable. In Zeile 61 definiere ich den neuen XQuery "$ruleNode/@filter/string()" um den Wert des Filter-Attributs auslesen. Dies fuehrt jedoch zu einem Null-Resultat. Kann mir jemand einen Tipp geben, wie der XQuery lauten muss? Variationen wie "$ruleNode/filter/string()" und "$ruleNode/filter" und "$ruleNode/@filter" habe ich einfach mal blind ausprobiert, mit demselben Ergebnis.

Nach meinem Verstaendnis wird mit dem Query "$ruleNode/@filter/string()" das Resultat des vorigen XQuerys an den neuen XQuery gebunden und $ruleNode steht fuer "/repository/mappings/rule". Entsprechend sollte ich mit "@filter" das Attribut ansprechen und mit "string()" den Datentyp vorgeben. Ist dem nicht so?

main.cpp

Code: Alles auswählen

#include <QCoreApplication>

#include <QtCore/QByteArray>
#include <QtCore/QBuffer>
#include <QtCore/QFile>
#include <QtCore/QStringList>
#include <QtCore/QTextStream>

#include <QtXmlPatterns/QXmlNodeModelIndex>
#include <QtXmlPatterns/QSimpleXmlNodeModel>
#include <QtXmlPatterns/QXmlQuery>
#include <QtXmlPatterns/QXmlResultItems>

#include <cstdlib>
#include <typeinfo>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QTextStream cout(stdout, QIODevice::WriteOnly);
    QFile sourceDocument;

    QString file = "resources/artifacts.xml";

    sourceDocument.setFileName(file);

    if(sourceDocument.open(QIODevice::ReadOnly))
    {
        QXmlQuery query;
        query.bindVariable("inputDocument", &sourceDocument);
        query.setQuery("doc($inputDocument)/repository/mappings/rule");

        if (!query.isValid())
        {
            cout << "query valid" << endl;
            exit(1);
        }

        QXmlResultItems results;
        query.evaluateTo(&results);
        const QXmlItem item = results.next();

        if (item.isNull())
        {
            cout << "query is null" << endl;
            exit(1);
        }
        else if( item.isNode())
        {
            cout << "item is node" << endl;
        }
        else if( item.isAtomicValue())
        {
            cout << "item is atomic" << endl;
        }

        QXmlQuery tmpQuery;

        tmpQuery.bindVariable("ruleNode", item);
        tmpQuery.setQuery("$ruleNode/@filter/string()");

        if (!tmpQuery.isValid())
        {
            cout << "tmpquery not valid" << endl;
            exit(1);
        }

        QXmlResultItems tmpResults;
        tmpQuery.evaluateTo(&tmpResults);
        const QXmlItem tmpItem = tmpResults.next();

        if (tmpItem.isNull())
        {
            cout << "tmpquery is null" << endl;
            exit(1);
        }
        else if( tmpItem.isNode())
        {
            cout << "tmpitem is node" << endl;
        }
        else if( tmpItem.isAtomicValue())
        {
            cout << "tmpitem is atomic" << endl;
        }

        QVariant atomic = tmpItem.toAtomicValue();
        cout << atomic.typeName() << endl; // outputs QString
        cout << tmpItem.toAtomicValue().toString() << endl; // is empty
    }
    else
        cout << "Could not read the XML document" << endl;

    exit(0);
    return a.exec();
}
Antworten