PDA

View Full Version : XML: accessing deep nodes



mentalmushroom
8th June 2011, 09:23
Hello. Is there a way to access XML nodes with something like this:


domDoc.elementsByTagName("methodResponse/params/param/value/struct/member")

instead of


QDomElement elem = domDoc.firstChildElement("methodResponse").firstChildElement("params").firstChildElement("param").firstChildElement("value").firstChildElement("struct").firstChildElement("member")


Here follows the sample XML document. I need to get access to all 'member' nodes.

<?xml version="1.0" encoding="utf-8"?>
<methodResponse>
<params>
<param>
<value>
<struct>
<member>
<name>token</name>
<value>
<string>532236bdf362493h5</string>
</value>
</member>
<member>
<name>status</name>
<value>
<string>200 OK</string>
</value>
</member>
<member>
<name>seconds</name>
<value>
<double>0.008</double>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodResponse>

wysota
8th June 2011, 09:42
See QXmlQuery.

ollerei
8th June 2011, 10:03
Or You can use XPath (http://www.w3schools.com/xpath/xpath_nodes.asp) to do the Query

mentalmushroom
8th June 2011, 12:33
Ok, thanks. Some another question... I receive xml from the network. It seems like QXmlQuery allows to use QNetworkReply in bindVariable method, e.g.

query.bindVariable("MyXml", reply);
But it doesn't work: evaluateTo hangs up for 5-10 seconds, then I see "First-chance exception at 0x760eb727 in SnelNL.exe: Microsoft C++ exception: bool at memory location 0x0034c20f.." in the output window.

However if I read data to QByteArray and create QBuffer with this data, query works fine.

Is it possible to use QNetworkReply directly in QXmlQuery::bindVariable as XML source?

wysota
8th June 2011, 13:37
Why not just use the doc() directive in the query itself?


QXmlQuery query;
query.setQuery("doc(http://www.qtcentre.org/index.php)/html/body/whatever");

mentalmushroom
8th June 2011, 14:16
I need to make a post request in order to receive a reply from server

wysota
8th June 2011, 15:43
In that case use QXmlQuery::setFocus() and pass it the network reply you receive. Just make sure you do it only after the data you expect has arrived.

mentalmushroom
9th June 2011, 06:56
Thanks, but still the same problem when I pass a reply as QIODevice. Below is the slot that is connected to QNetworkAccessManager::finished signal, so all the data must be arrived, I think.


void MyClass::authenticationFinished(QNetworkReply *reply)
{
QXmlQuery query;
query.setFocus(reply);
query.setQuery("methodResponse/params/param/value/struct/member[name=\"token\"]/value/string(string)");
// ...
}

The following code works fine:


void MyClass::authenticationFinished(QNetworkReply *reply)
{
QXmlQuery query;
query.setFocus(reply->readAll()); // !pass the string
query.setQuery("methodResponse/params/param/value/struct/member[name=\"token\"]/value/string(string)");
// ...
}