c++qtxqueryqxmlquery

How to solve the error FODC0002 when using QXmlFormatter?


I'm trying to use QXmlQuery to get some elements from a XML file. Everything works fine (I'm able to validate the source XML file and etc) until I get to the part in which I try to use QXmlFormatter, in order to write the results to another XML file. When I get to this part, the following error is shown: Error FODC0002 in tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:inputDocument, at line 1, column 0: Premature end of document.

The code is based on the "Recipes" project available as an example in Qt. The only difference here is that I made a simpler version of the "cookbook" XML file. I've tried to use QBuffer(the approach implemented in the example) instead of a file, but as expected, got the same result.

Here is the source XML, called temp2_xml.xml

<?xml version="1.0" encoding="UTF-8"?>
<cookbook>
    <recipe>
    <title>Quick and Easy Mushroom Soup</title>
    <title>Cheese on Toast</title>
    </recipe>
</cookbook>

Here is the Xquery file, called allRecipes.xq:

(: Select all recipes. :)
declare variable $inputDocument external;

doc($inputDocument)/cookbook/recipe/<p>{string(title)}</p>

And here's the code:

     QFile aqr_xq("C:/test_xml/allRecipes.xq");
     aqr_xq.open(QIODevice::ReadOnly);
     QFile file("C:/test_xml/temp_xml.xml");
     file.open(QIODevice::ReadWrite);
     QFile aqr_r;
     aqr_r.setFileName("C:/test_xml/temp2_xml.xml");
     aqr_r.open(QIODevice::ReadOnly);
     QTextStream in(&aqr_r);
     QString inputDocument = in.readAll();
     const QString str_query(QString::fromLatin1(aqr_xq.readAll()));
     QXmlQuery query;
     query.bindVariable("inputDocument",&aqr_r);
     query.setQuery(str_query);
     bool debug_xml = false;
     debug_xml = query.isValid();
     QXmlFormatter ser(query, &file);
     query.evaluateTo(&ser);

Any ideas about what's causing the problem and how to solve it?


Solution

  • I think the problem is indeed the use of the text stream to consume the opened file, if I don't use that and simply use the code

     QFile aqr_xq(queryFile);
     aqr_xq.open(QIODevice::ReadOnly);
     QFile file(outputFile);
     file.open(QIODevice::ReadWrite);
     QFile aqr_r;
     aqr_r.setFileName(inputFile);
     aqr_r.open(QIODevice::ReadOnly);
     const QString str_query(QString::fromLatin1(aqr_xq.readAll()));
     QXmlQuery query;
     query.bindVariable("inputDocument",&aqr_r);
     query.setQuery(str_query);
     bool debug_xml = false;
     debug_xml = query.isValid();
     QXmlFormatter ser(query, &file);
     query.evaluateTo(&ser);
    

    then indeed the error is in the XQuery and is raised as

    Error XPTY0004: Required cardinality is zero or one("?"); got cardinality one or more("+").
    

    You haven't said which output you want to create but if you I change the XQuery to e.g.

    declare variable $inputDocument external;
    
    doc($inputDocument)/cookbook/recipe/title/<p>{string()}</p>
    

    then the C++ code runs fine.

    Note also that you can load the XQuery directly from a file by using

    query.setQuery(QUrl(queryFile));