PDA

View Full Version : QAbstractXmlNodeModel implementation - QDomNodeModel / QXmlQuery



sadaszewski
8th January 2011, 17:02
I have prepared an implementation (BSD licensed) of QAbstractXmlNodeModel class from QtXmlPatterns module which makes it possible to run QXmlQuery-ies on a QDomDocument. I've called it QDomNodeModel.

Here's an usage example:


QDomDocument doc;

doc.setContent(QString("<root><elem someAttr='attrValue'><subElem1 /><subElem2 /></elem></root>"), (QString*) 0, (int*) 0, (int*) 0);

QXmlQuery q(QXmlQuery::XQuery10);

QDomNodeModel m(q.namePool(), doc);

q.setFocus(QXmlItem(m.fromDomNode(doc.documentElem ent())));

q.setQuery("elem/@someAttr");

QXmlResultItems res;
q.evaluateTo(&res);

while (!res.next().isNull())
{
QDomElement elem = m.toDomNode(res.current().toNodeModelIndex()).toEl ement();
qDebug() << m.toDomNode(res.current().toNodeModelIndex()).toAt tr().value();
}


Download link: http://algoholic.eu/wp-content/uploads/2011/01/qdomnodemodel.tar.gz

wysota
8th January 2011, 17:55
How does it differ from this?
http://developer.qt.nokia.com/quarterly/view/querying_generic_data_with_xquery

sadaszewski
8th January 2011, 18:05
Well...

1) It's written in C++, not in Python.
2) It's not an example for some generic data. It's a working implementation for QDomDocument, which is exactly what I needed (and suppose most people do when they start using QtXmlPatterns along with DOM).

:)

TimShnaider
26th May 2012, 02:17
Hi Stanislaw,

I would have posted another comment on your blog, but it has gone dead since yesterday, will post there again when live.

I've discovered the culprit for performance - compareOrder.
It seems to be very inefficient, profiler screenshot shows hot path.
Returning any hard-coded DocumentOrder at beginning of function results in almost instantaenous performance vs 5 seconds before parsing a tree with hundreds of nodes.

Will push my poor c++ skills to the limit trying to optimise, hope you can help.

Full sized screenshot here: http://www.xemware.com/private/compareOrder.png

TimShnaider
26th May 2012, 04:30
I've been playing around, trying things like caching paths and child indexes and realising that wasn't go to work due to getting copies of nodes and possibly having to redesign the whole implementation to use pointers etc.
But unless I'm missing something, this works just as well and is QUICK. Results are as expected for initial testing.

QXmlNodeModelIndex::DocumentOrder QDomNodeModel::compareOrder (
const QXmlNodeModelIndex & ni1,
const QXmlNodeModelIndex & ni2 ) const
{
QDomNode n1 = toDomNode(ni1);
QDomNode n2 = toDomNode(ni2);
if (n1 == n2)
return QXmlNodeModelIndex::Is;

int l1 = n1.lineNumber();
int c1 = n1.columnNumber();
int l2 = n2.lineNumber();
int c2 = n2.columnNumber();

if ( l1 < l2 )
return QXmlNodeModelIndex::Precedes;

if ( l1 > l2 )
return QXmlNodeModelIndex::Follows;

if ( l1 == l2 && c1 < c2 )
return QXmlNodeModelIndex::Precedes;
else
return QXmlNodeModelIndex::Follows;

kleag
6th April 2017, 10:46
Thanks a lot for the proposed implementation of compareOrder. I had an occurrence on which the inilial implementation was running for an infinite time (more or less 1 minute). Your implementation is quite immediate with no change in results.