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?
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));