QXmlQuery

Alles rund um die Programmierung mit Qt
Antworten
stardust5383
Beiträge: 28
Registriert: 31. Oktober 2009 10:36

QXmlQuery

Beitrag von stardust5383 »

Hallo zusammen,

ich habe bei der Abfrage eines XML Files ein sehr komisches Problem. Ich mache erst einen ersten Query auf mein File und hole mir alle profile knoten nach QXmlResultItems. Diese Arbeite ich innerhalb einer while Schleife ab und führe da nochmals Querys durch um die Werte innerhalb des Knotens abzufragen. Hier meine Methode:

Code: Alles auswählen

Reciepe* ReciepeBuilder::getItem( void )
{
	QFileInfo fileInfo = this->lFiles.at(this->nIndex);
	QXmlResultItems result;
	QXmlQuery query;
	QMap<QString, ReciepeItem*> ProfileMap;
	
	if (!fileInfo.isFile())
		return NULL;
	else {
		// Lade das XML File in einen String um es zu parsen
		QFile source;
		source.setFileName(fileInfo.absoluteFilePath());

		if (!source.open(QIODevice::ReadOnly)) {
			qWarning("Unable to open file");
			return NULL;
		}
		else {
			// Erst holen wir uns die Metadaten aus dem Rezept
			query.bindVariable("inputDocument", &source);

						query.setQuery("declare default element namespace 'http://www.example.org/recipe'; doc($inputDocument)//recipe/profile");

			// Prüfe den Query
			if (query.isValid()) {
				query.evaluateTo(&result);

				QXmlItem item(result.next());

				while (!item.isNull()) {
					
					// Erstellungsdaten für eine Schicht
					QString cName;		// Name des Profils
					short nid;			// ID

					double d_height;	// Höhe der Schicht in um
					double d_weight;
					double d_warn;		// Warngrenze
					double d_info;		// Alarmgrenze
			
					// Query Objekte
					QXmlQuery tmpQuery;
					QXmlResultItems tmpResult;
					QXmlItem tmp;
					// Hier erfolgt die Bindung des Items an den Query
					tmpQuery.bindVariable("profileNode", item);

					// Führe den ersten Query aus um den Namen der Schicht zu erhalten
					tmpQuery.setQuery("declare default element namespace 'http://www.example.org/recipe'; $profileNode/@name/string()");
					tmpQuery.evaluateTo(&tmpResult);
					tmp = tmpResult.next();

					// Wenn es ein Atomic Value gibt, schreibe in in cName
					if (tmp.isAtomicValue())
						cName = QString(tmp.toAtomicValue().toString());

					// Hier holen wir uns die ID der Schicht
					tmpQuery.setQuery("declare default element namespace 'http://www.example.org/recipe'; $profileNode/@id/string()");
					tmpQuery.evaluateTo(&tmpResult);
					tmp = tmpResult.next();

					if (tmp.isAtomicValue())
						nid = (short)tmp.toAtomicValue().toUInt();
			
					// Hier wird die Schichthöhe gesucht
					tmpQuery.setQuery("declare default element namespace 'http://www.example.org/recipe'; xs:double($profileNode/height/string())");
					tmpQuery.evaluateTo(&tmpResult);
					tmp = tmpResult.next();

					if (tmp.isAtomicValue()) {
						qDebug() << "Höhe: " << tmp.toAtomicValue().toDouble();
					}

					if (tmp.isNode()) {
						qDebug() << "Node detected";
					}

					if (tmp.isNull()) {
						qDebug() << "Is Null";
					}

					// DEBUGGING
					qDebug() << "Schicht:" << cName << " ID:" << nid << "Höhe:" << d_height;
					
					item = result.next();
				}
			}
		}
	}
}
Es funktioniert bis auf eine Sache:

Code: Alles auswählen

tmpQuery.setQuery("declare default element namespace 'http://www.example.org/recipe'; xs:double($profileNode/height/string())");
Hier gibt es kein Ergebnis, obwohl der Knoten <height>1.00</height> in der XML unterhalb von profile vorhanden ist. Setze ich für height den knoten <error>1.00</error> ein, welcher ebenfalls vorhanden ist - funktioniert es. Ich habe keine Ahnung, wieso es nur bei error funktioniert, aber bei keinem anderen knoten unterhalb von profile.

Bin echt am verzweifeln und hoffe das mir einer von euch weiterhelfen kann.
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

vielleicht<heigth>1.00</heigth> statt <height>1.00</height> drin?
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
stardust5383
Beiträge: 28
Registriert: 31. Oktober 2009 10:36

Beitrag von stardust5383 »

Das dachte ich auch erst. Mittlerweile habe ich mal bisschen getestet und festgestellt, dass wenn ich meinen Node <error> in <alarm> umbenenne (natürlich auch in der xsd) ebenfalls kein Ergebnis kommt. Von 5 nodes <warning> <error> <height> <weight> <color> funktioniert also nur der Knoten Error. Kann das ein Bug in den XMLPatterns sein oder ist einfach mein parse Ansatz falsch?
stardust5383
Beiträge: 28
Registriert: 31. Oktober 2009 10:36

Beitrag von stardust5383 »

Hier mal meine xsd die ich einbinde und die verwendete xml.

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
	targetNamespace="http://www.example.org/recipe" xmlns:recipe="http://www.example.org/recipe"
	elementFormDefault="qualified">
	
	<xs:element name="recipe">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="meta">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="author" type="xs:string" />
							<xs:element name="created" type="xs:dateTime" />
							<xs:element name="modified" type="xs:dateTime" />
							<xs:element name="reference" type="xs:string" />
						</xs:sequence>
					</xs:complexType>
				</xs:element>
				<xs:element name="profile" minOccurs="1" maxOccurs="unbounded">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="weight" type="xs:double" />
							<xs:element name="color">
								<xs:complexType>
									<xs:attribute name="min" type="xs:positiveInteger" />
									<xs:attribute name="max" type="xs:positiveInteger" />
									<xs:attribute name="middle" type="xs:positiveInteger" />
								</xs:complexType>
							</xs:element>
							<xs:element name="warning" type="xs:double" />
							<xs:element name="error" type="xs:double" />
              <xs:element name="height" type="xs:double" />
						</xs:sequence>
						<xs:attribute name="id" type="xs:string" />
						<xs:attribute name="name" type="xs:string" />
					</xs:complexType>
				</xs:element>
			</xs:sequence>
			<xs:attribute name="name" type="xs:string" />
			<xs:attribute name="id" type="xs:string" />
			<xs:attribute name="clientid" type="xs:string" />
		</xs:complexType>
	</xs:element>
	
</xs:schema>
hier die xml:

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
<recipe name="DDD" id="23-122-243" clientid="DD115"
	xmlns="http://www.example.org/recipe"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.example.org/recipe recipe.xsd ">
	<meta>
		<author>Max Mustermann</author>
		<created>2010-06-25T10:00:00+02:00</created>
		<modified>2010-06-26T10:00:00+02:00</modified>
		<reference>ddd.bmp</reference>
	</meta>
	<profile id="1" name="Des3">
		<weight>12.00</weight>
		<color min="20" max="255" middle="44"></color>
		<warning>6.05</warning>
		<error>7.05</error>
		<height>6.00</height>
	</profile>
	<profile id="2" name="Des2">
		<weight>12.00</weight>
		<color min="20" max="255" middle="44"></color>
		<warning>6.05</warning>
		<error>7.00</error>
		<height>6.00</height>
	</profile>
	<profile id="3" name="Des1">
		<weight>12.00</weight>
		<color min="20" max="255" middle="44"></color>
		<warning>6.05</warning>
		<error>7.00</error>
		<height>6.00</height>
	</profile>
	<profile id="4" name="Des4">
		<weight>12.00</weight>
		<color min="20" max="255" middle="44"></color>
		<warning>6.05</warning>
		<error>7.00</error>
		<height>6.00</height>
	</profile>
</recipe>
stardust5383
Beiträge: 28
Registriert: 31. Oktober 2009 10:36

Beitrag von stardust5383 »

Keiner mehr eine Idee?
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

Ist das xsd einrückungssensitiv?
das height element ist "falsch" eingerückt ...
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
stardust5383
Beiträge: 28
Registriert: 31. Oktober 2009 10:36

Beitrag von stardust5383 »

Also ich habe meine xsd übrprüft. Kopiere sie jetzt hier mal 1:1. Ich finde da keinen Einrückugsfehler. Alles ist doch so wie es sein sollte. Ich komm an alle Daten ran außer warning, height und color?!

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
	targetNamespace="http://www.example.org/recipe" xmlns:recipe="http://www.example.org/recipe"
	elementFormDefault="qualified">
  <xs:element name="recipe">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="meta">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="author" type="xs:string" />
              <xs:element name="created" type="xs:dateTime" />
              <xs:element name="modified" type="xs:dateTime" />
              <xs:element name="reference" type="xs:string" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="profile" minOccurs="1" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="weight" type="xs:double" />
              <xs:element name="color">
                <xs:complexType>
                  <xs:attribute name="min" type="xs:positiveInteger" />
                  <xs:attribute name="max" type="xs:positiveInteger" />
                  <xs:attribute name="middle" type="xs:positiveInteger" />
                </xs:complexType>
              </xs:element>
              <xs:element name="warning" type="xs:double" />
              <xs:element name="error" type="xs:double" />
              <xs:element name="height" type="xs:double" />
            </xs:sequence>
            <xs:attribute name="id" type="xs:string" />
            <xs:attribute name="name" type="xs:string" />
          </xs:complexType>
        </xs:element>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string" />
      <xs:attribute name="id" type="xs:string" />
      <xs:attribute name="clientid" type="xs:string" />
    </xs:complexType>
  </xs:element>
</xs:schema>
Antworten