0

Edit I have added a minumum working code sample that produces the same errors at the bottom...

I have an xsd schema file and an xml file, both of which I have validated online, and I have used online tools to validate the xml file using my xsd schema. Everything is valid and compatible. I am now trying to use QXmlSchemaValidator to validate the same xml, using the same xsd, however, when I call:

if (!validator.validate(file.fileName()))

it returns false.

Here is the code snippet in which this happens:

LoadInfo JobTreeControl::loadXML_schemaValidation(QFile& file, QXmlStreamReader& iXml)
{
    QString schemeFilePath = QCoreApplication::applicationDirPath() + "/schema.xsd";
    QFile schemaFile(schemeFilePath);

    if (!schemaFile.open(QFile::ReadOnly | QFile::Text))
        return LoadInfo(false, "Schema file failed to open");

    QXmlSchema schema;

    if (!schema.load( QUrl::fromLocalFile(schemeFilePath)))
        return LoadInfo(false, "Qt schema failed to load schema file");

    if (!schema.isValid())
        return LoadInfo(false, "Schema is invalid");

    QXmlSchemaValidator validator(schema);

    if (!validator.validate(file.fileName()))
        return LoadInfo(false, "Load file is not a valid Pointfuse Batch Utility XML file");

    return LoadInfo(true);
}

I also get some interesting console output from the schema and validator:

QObject::connect: Cannot connect (null)::aboutToQuit() to QNativeWifiEngine::closeHandle() QEventLoop: Cannot be used without QApplication QEventLoop: Cannot be used without QApplication Error FODC0002 in c:/test Data/serializeArchive/test_newSaveFormat.xml, at line 1, column 0: Premature end of document.

I have tried googling these errors and QXmlSchema issues, and I'm not having much luck turning up anything. I did find this post which is close:

QEventLoop: Cannot be used without QApplication

...but his issue was that he didn't have an instance of QApplication running and therefor no event loop. I can tell you for certain that I do, as this code snippet is very deep inside my application, and is accessed when clicking on a QAction and having a QDialog pop up.

Below I'll write out which lines of code cause which console outputs:

QXmlSchema schema;

QObject::connect: Cannot connect (null)::aboutToQuit() to QNativeWifiEngine::closeHandle()

    if (!schema.load( QUrl::fromLocalFile(schemeFilePath)))

QEventLoop: Cannot be used without QApplication

    if (!validator.validate(file.fileName()))

QEventLoop: Cannot be used without QApplication Error FODC0002 in c:/test Data/serializeArchive/test_newSaveFormat.xml, at line 1, column 0: Premature end of document.

Thanks in advance for any help you can give,

Pete

Edit:

I can also confirm that both the xml filepath use to load QFile file, and the schemaFilePath used to load QFile schemaFile, are correct. Though this is confirmed when I successfully open and load each of these files.

Edit

And I'm curious to know why on earth my QXmlSchema is calling functions relating to QNativeWifiEngine... What does that have to do with the schema?

Edit With Minimum Working Example Code

I have written the shortest working example I can think of.

Bellow is the c++/Qt source:

class XmlValidator : public QDialog
{

public:

    XmlValidator()
        : QDialog()
    {
        QVBoxLayout* p_vBoxLayout = new QVBoxLayout;
        QPushButton* p_pushButton = new QPushButton("Validate XML");

        p_vBoxLayout->addWidget(p_pushButton);
        this->setLayout(p_vBoxLayout);

        connect(p_pushButton, &QPushButton::clicked, this, &XmlValidator::validateXML);
    }

    void validateXML(); 
};

void XmlValidator::validateXML()
{
    QString xmlFilePath = QCoreApplication::applicationDirPath() + "/testXml.xml";
    QString schemeFilePath = QCoreApplication::applicationDirPath() + "/testSchema.xsd";

    QFile xmlFile(xmlFilePath);
    QFile schemaFile(schemeFilePath);

    if (!xmlFile.open(QFile::ReadOnly | QFile::Text))
    {
        std::cout << "Xml file failed to open" << std::endl;
        return;
    }

    if (!schemaFile.open(QFile::ReadOnly | QFile::Text))
    {
        std::cout << "Schema file failed to open" << std::endl;
        return;
    }

    QXmlSchema schema;

    if (!schema.load(QUrl::fromLocalFile(schemeFilePath)))
    {
        std::cout << "Qt schema failed to load schema file" << std::endl;
        return;
    }

    if (!schema.isValid())
    {
        std::cout << "Schema is invalid" << std::endl;
        return;
    }

    QXmlSchemaValidator validator(schema);

    if (!validator.validate(xmlFilePath))
    {
        std::cout << "Xml file is not a valid" << std::endl;
        return;
    }
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    XmlValidator dialog;

    dialog.show();

    return a.exec();
}

Then testXml.xml

<?xml version="1.0" encoding="UTF-8"?>
<testSchemaElement version="4.5"/>

And finally testSchema.xsd

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="testSchemaElement">
    <xs:complexType>
        <xs:attribute name="version" type="xs:decimal"/>
    </xs:complexType>
</xs:element>

</xs:schema>

The c++ application will look for these two files in it's working directory.

Iron Attorney
  • 1,003
  • 1
  • 9
  • 22
  • The SO article you mentoined has a comment **a QCoreApplication a(argc, argv);** would be sufficient. Did you tried this (create instance without using the exec() function). Not very beautiful, but may help.. – Willy K. Oct 13 '17 at 12:10
  • QApplication a(argc, argv); is the very first line of my main function, unless you're suggesting I add another instance elsewhere? – Iron Attorney Oct 13 '17 at 13:21
  • @IronAttorney Don't add a second, one is enough. Maybe `loadXML_schemaValidation()` is executed before `main()` ? – Benjamin T Oct 13 '17 at 14:46
  • I'm afraid it's not. Everything that happens in my app starts in main. As I said, I am triggering this function from a QDialog that I opened by clicking on a QAction in my GUI, all of which utilized signals and slots to make this work. I'm trying to make a small compilable test case, but however I slice it, I need to make a user interface to trigger the Xml schema functions, otherwise I can't call exec on QApplication AND use the schema, haha – Iron Attorney Oct 13 '17 at 15:04
  • 1
    If I remember well, QXmlSchema uses network functionality to access the files (the fact that it uses QUrl is an hint). Also, why do you open `schemaFile`? You do not need to, you just need to pass the path to QUrl. – Benjamin T Oct 13 '17 at 17:00
  • I read that you have to open it with at least the QFile::ReadOnly option in order to use it with the schema. And thanks for pointing out the QUrl business, that does make more sense – Iron Attorney Oct 13 '17 at 17:05
  • I've nearly finished the minimum compilable example, I'll post it up as an edit when I have... – Iron Attorney Oct 13 '17 at 17:06
  • sorry, got to bump this – Iron Attorney Oct 16 '17 at 09:51

0 Answers0