I often write code that iterates over an XML document and performs actions on elements with some specifig tag. Usually I do it using code like the following:
for(QDomElement elem = parent.firstChildElement("tag"); !elem.isNull(); elem = elem.nextSiblingElement("tag")){ doSomething(elem); } |
This is fine, but I thought it’d be nicer to do it using the foreach() loop offered by Qt. Out of the box Qt doesn’t allow to use foreach with xml documents, so I decided to do something about it
After 15 minutes the class was ready:
#include#include #include class DomElementContainer { public: class const_iterator { friend class DomElementContainer; public: const_iterator(){} const_iterator &operator++(){ m_e = m_e.nextSiblingElement(m_t); return *this; } const QDomElement & operator*(){ return m_e; } bool operator==(const const_iterator &other) const { return (m_e==other.m_e && m_t==other.m_t); } bool operator!=(const const_iterator &other) const { return (m_e!=other.m_e || m_t!=other.m_t); } private: const_iterator(const QDomElement &e, const QString &t){ m_e = e; m_t = t; } QDomElement m_e; QString m_t; }; DomElementContainer(const QDomElement &e, const QString &tag=QString::null){ m_tag = tag; m_elem = e; } DomElementContainer(const QDomDocument &d, const QString &tag=QString::null){ m_tag = tag; m_elem = d.documentElement(); } const_iterator begin() const{ return const_iterator(m_elem.firstChildElement(m_tag), m_tag); } const_iterator end() const { return const_iterator(QDomElement(), m_tag); } private: QDomElement m_elem; QString m_tag; };
Now it’s possible to do the following:
#include "domelementcontainer.h" const char *xml = ""; int main(){ QDomDocument doc; doc.setContent(QString(xml)); DomElementContainer c(doc, "tag"); foreach(QDomElement e, c) qDebug("%s", qPrintable(e.text())); return 0; } content 1 content 2 " "wrongcontent " "content 3
Download available here.