Seite 1 von 1

[gelöst]Error XSDError in file... Premature end of document.

Verfasst: 13. September 2011 16:24
von shinji
Hallo!

Ich versuche mich gerade daran, mit QXmlSchema eine XSD-Datei zu validieren. Wenn die Datei wirklich einen Fehler enthält liefert QXmlSchema::isValid() auch false zurück. Aber wenn die Datei eigentlich stimmen müsste (isValid() sagt true) wird auf der Konsole trotzdem immer die folgende Meldung ausgegeben:

Code: Alles auswählen

Error XSDError in file:///X:/Private%20Daten/Develop/QT4/DSTool/xsd/helloWorld.xsd, at line 1, column 0: Premature end of document.
Scheinbar ist das aber trotz des XSDError kein Fehler, denn das Dokument ist ja gültig. Was kann das sein und wie kann ich das abfangen bzw. verhindern?

Die XSD-Datei hat folgenden Inhalt:

Code: Alles auswählen

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

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<xsd:element name="p" type="xsd:string"/>
</xsd:schema>
Gruß
Thorsten

Re: Error XSDError in file... Premature end of document.

Verfasst: 13. September 2011 16:59
von Christian81
Mangels minimalen kompilierbaren Beispiel kann man dazu leider nichts sagen...

Re: Error XSDError in file... Premature end of document.

Verfasst: 13. September 2011 19:16
von shinji
Ok :)

Hier die Klasse:

Code: Alles auswählen

#include <QtXmlPatterns/QXmlSchema>
#include <QAbstractMessageHandler>
#include <QFile>
#include <QDebug>
#include <QMessageBox>
#include <QString>
#include <QWidget>
#include <QUrl>
#include <QFileInfo>
#include <QDateTime>
#include "xmlvalidator.h"

XmlValidator::XmlValidator(QObject *parent)
{
    modificationDate.setMSecsSinceEpoch(0);
    xsdFile = "";
}

void XmlValidator::importXsdFile(QString filename)
{
    QFile file;
    MessageHandler messageHandler;

    if ( QFileInfo(xsdFile).canonicalFilePath() == QFileInfo(filename).canonicalFilePath() )
    {
        file.setFileName(QFileInfo(xsdFile).canonicalFilePath());
    }
    else
    {
        file.setFileName(QFileInfo(filename).canonicalFilePath());
    }

    // Datei oeffnen
    file.open(QIODevice::ReadOnly | QIODevice::Text);

    // Wenn die Datei nicht existiert bzw. nicht lesbar ist abbrechen
    if (!file.isReadable())
    {
        emit onXsdFileReadError(QFileInfo(file).canonicalFilePath());
        file.close();
    }
    else
    {
        // Temporaeres Schema damit das eventuell vorhandene
        // nicht ueberschrieben wird
        QXmlSchema tmp_schema;
        tmp_schema.setMessageHandler(&messageHandler);

        if (tmp_schema.load( &file, QUrl::fromLocalFile(file.fileName()) ))
        {
            // Temp. Laden erfolgreich. Jetzt richtig
            schema.load(&file, QUrl::fromLocalFile(file.fileName()));
            modificationDate = QFileInfo(file).lastModified();
            xsdFile = QFileInfo(file).canonicalFilePath();
            schemaText = QString::fromUtf8(file.readAll());

            emit onXsdFileImported(QFileInfo(file).canonicalFilePath());
            
            file.close();
        }
        else
        {
            emit onXsdFileInvalid(QFileInfo(file).canonicalFilePath(), messageHandler.getStatusMessage(), messageHandler.getLine(), messageHandler.getColumn());
            file.close();
        }
    }
}
Die dazu gehörende Header-Datei

Code: Alles auswählen

#include <QMainwindow>
#include <QObject>
#include <QFile>
#include <QFileInfo>
#include <QAbstractMessageHandler>
#include <QDateTime>
#include <QtXmlPatterns/QXmlSchema>

class XmlValidator : public QWidget
{
    Q_OBJECT
public:
    explicit XmlValidator(QObject *parent = 0);

    void importXsdFile(QString);

private:
    QString xsdFile;
    QXmlSchema schema;
    QString schemaText;
    QDateTime modificationDate;

signals:
    void onXsdFileInvalid(QString, QString, int, int);
    void onXsdFileReadError(QString);
    void onXsdFileImported(QString);

public slots:

};
Die MessageHandler Klasse habe ich einfach einmal weggelassen. Die fängt nur die Fehlermeldungen zur Weitergabe an das MainWindow ab.

--edit--
habe hinter dem schemaText=.... noch die folgende Zeile hinzugefuegt. Aber die Ausgabe ist auch nicht so wie ich es mir denke:

Code: Alles auswählen

qWarning() << "Bytes: " << QFileInfo(file).size() << " Inhalt: " << schemaText;
Ergibt auf der Konsole:

Code: Alles auswählen

Bytes:  158  Inhalt:  "" 
Kein Inhalt des Schemas?!

--edit2--
Das Schema ist zumindest laut w3.org validator super:

Code: Alles auswählen

Schema validating with XSV 3.1-1 of 2007/12/11 16:20:05
   Target: [standalone schema assessment]
   (Real name: helloWorld.xsd)schemaDocs: file:/usr/local/XSV/xsvlog/tmpmdllWxuploaded
   The schema(s) used for schema-validation had no errors
   The target was not assessed
--edit3--
Scheinbar darf man auf ein Qfile nur ein einziges mal load() ausführen.

Bei folgenden Beispiel ist das zweite tmp_schema.load() FALSE:

Code: Alles auswählen

QXmlSchema tmp_schema;

if (tmp_schema.load( &file, QUrl::fromLocalFile(file.fileName())))
    qWarning("GUELTIG tmp");

if (!schema.load( &file, QUrl::fromLocalFile(file.fileName())))
    qWarning"UNGUELTIG!");
Nehme ich die erste if-Abfrage raus ist das zweite load gültig! Verstehe ich nicht O.O

Re: Error XSDError in file... Premature end of document.

Verfasst: 13. September 2011 20:24
von shinji
Ich bekomme Pocken.... so geht es:

Code: Alles auswählen

if (tmp_schema.load( &file, QUrl::fromLocalFile(file.fileName()) ))
        {
            file.reset();

            // Temp. Laden erfolgreich. Jetzt richtig
            schema.setMessageHandler(&messageHandler);
            schema.load(&file, QUrl::fromLocalFile(file.fileName()));
            modificationDate = QFileInfo(file).lastModified();
            xsdFile = QFileInfo(file).canonicalFilePath();

            file.reset();

            schemaText = QString::fromUtf8(file.readAll());

            qWarning() << "Bytes: " << QFileInfo(file).size() << " Inhalt: " << schemaText;
...
Ausgabe

Code: Alles auswählen

Bytes:  158  Inhalt:  "<?xml version="1.0" encoding="UTF-8"?>

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<xsd:element name="p" type="xsd:string"/>
</xsd:schema>" 
Es fehlten zwei dumme file.reset() :/