c++ qt xpath xquery

c++ - Extracción de valores de nodo secundarios con QXmlItem como un foco QXmlQuery



qt xpath (4)

Debería funcionar así:

QDomDocument doc("structure"); QFile file("structure.xml"); if( !file.open( IO_ReadOnly ) ) return -1; if( !doc.setContent( &file ) ) { file.close(); return -2; } file.close(); QDomElement root = doc.documentElement(); if( root.tagName() != "data" ) return -3; QDomNode n = root.firstChild(); while( !n.isNull() ) { QDomElement e = n.toElement(); if( !e.isNull() ) { if( e.tagName() == "x" ) { QMessageBox::information( 0, "X", e.attribute("id", "")+ "/n" + e.attribute("nam", "" ) + "/n" + e.attribute("tab", "")); } } n = n.nextSibling(); }

El código está haciendo un cuadro de mensaje para cada x (no tiene qt en esta máquina, por lo que no puede probarlo ahora)

He intentado obtener valores de texto de nodo de este archivo XML:

<!DOCTYPE structure> <data> <x> <id>1</id> <nam>tytuł</nam> <tab>21</tab> <ind>5</ind> <pre>TY</pre> <khw>C.TY</khw> </x> <x> <id>2</id> <nam>autor</nam> <tab>21</tab> <ind>5</ind> <pre>FO</pre> <khw>C.FO</khw> </x> <x> <id>3</id> <nam>hasło korporatywne</nam> <tab>21</tab> <ind>5</ind> <pre>FN</pre> <khw>C.FN</khw> </x> </data>

Lo que quiero hacer es buscar cada nodo y sus hijos y convertirlo a QMap. No tengo problemas para obtener un solo elemento, pero cuando se trata de obtener elementos secundarios estableciendo el resultado de QXmlQuery como foco, el QString que evalúo la consulta del nodo secundario está vacío. Yo uso este fragmento de código:

QXmlResultItems results; QFile structure("./structure.xml"); // xml file, as described earlier structure.open(QFile::ReadOnly); QXmlQuery query; query.setFocus(&structure); query.setQuery("data/x"); query.evaluateTo(&results); QXmlItem next = results.next(); while(!next.isNull()) { qDebug() << next.toNodeModelIndex().stringValue(); // everything''s fine. It prints contents of <x>''s child nodes QXmlQuery childQuery; QString r; childQuery.setFocus(next); childQuery.setQuery("./nam/text()"); // already tested: "/nam/text()", "/nam/string()", "x/nam/string()", "data/x/nam/string()" etc... still no luck. childQuery.evaluateTo(&r); qDebug() << r; // prints /n but it should print content of <nam> node. next = results.next(); }

Software que uso: Qt 4.7.2 SDK directamente desde el sitio web de Qt, QtCreator 2.3.1 en Windows y Linux (sin ninguna diferencia en este caso en particular, los resultados son los mismos). Quiero estar seguro de que ese es el problema de mi falta de conocimiento, en lugar de error de software, por favor ayuda


En lugar de usar evaluateTo( QString * ) use la versión de QStringList . Deberia de funcionar.


Tuve el mismo problema, y ​​la solución fue hacer que la query y childQuery fueran exactamente iguales. Podrías reescribir tu código como:

while(!next.isNull()) { qDebug() << next.toNodeModelIndex().stringValue(); QString r; query.setFocus(next); query.setQuery("./nam/text()"); query.evaluateTo(&r); qDebug() << r; next = results.next(); }

si childQuery debe estar en otro procedimiento, debe pasarlo por referencia.


Desafortunadamente, de Qt Documentation no está claro que en los casos en que desee utilizar la QXmlQuery::setFocus(const QXmlItem& item) para consultar nodos secundarios, debe crear objetos QXmlQuery correspondientes utilizando el QXmlQuery(const QXmlNamePool& np) para hacerlos comparte el mismo objeto QXmlNamePool . Tal intercambio, simplemente hablando, relaciona las consultas entre sí.

Teniendo esto en cuenta, su ejemplo debería verse de la siguiente manera:

QFile structure("./structure.xml"); structure.open(QFile::ReadOnly); QXmlQuery query; query.setFocus(&structure); query.setQuery("data/x"); QXmlResultItems results; query.evaluateTo(&results); QXmlQuery childQuery(query.namePool()); while (!results.next().isNull()) { childQuery.setFocus(results.current()); childQuery.setQuery("nam/text()"); QString r; childQuery.evaluateTo(&r); qDebug() << r; }

Además, puede ir más allá y reutilizar el objeto QXmlQuery inicial:

QFile structure("./structure.xml"); structure.open(QFile::ReadOnly); QXmlQuery query; query.setFocus(&structure); query.setQuery("data/x"); QXmlResultItems results; query.evaluateTo(&results); while (!results.next().isNull()) { query.setFocus(results.current()); query.setQuery("nam/text()"); QString r; query.evaluateTo(&r); qDebug() << r; }