Обычный вариант с рекурсией:
void MyClass::process(QDomNode node)
{
QDomNodeList nodeList = node.childNodes();
for (int i = 0; i < nodeList.count(); ++i) {
// some stuff
if (node.childNodes().at(i).hasChildNodes())
process(nodeList.at(i));
}
}
переход от рекурсии к итерации производится через создание собственного стека FILO (при рекурсии используется стек вызовов)
инициализация стека: кладём в стек первый (первые) элемент;
while(стек не пуст)
{
извлечь текущий элемент из стека -> curr;
исследование и обработка curr , в процессе обработки в стек заносятся ещё элементы;
}
Да, такой способ я видел, но увы QDomDocument не умеет переходить на следующий элемент.
По этому такой вариант не работает:
QDomNode node = m_doc.firstChild();
while (!node.isNull()) {
// some stuff
node = node.nextSibling();
}
Так как node.nextSibling не умеет проверять дочерние элементы. А так как структура xml мне заранее не известна, то не ясно как пройтись по дереву таким способом.
QDomNodeList list;
list.append (root_node);
while (!list.empty ()) {
QDomElement el = list.takeAt (0).toElement ();
do_stuff (el);
list.append (el.childNodes ());
};
RazrFalcon, node.nextSibling(); находит соседний тег , таким образом ты перебираешь теги одного уровня в текущей "области видимости". Каждый тег помещаешь в стек. Новая итерация извлекает элемент и идёт уже по его чайлдам. Понимаешь фишку ? Поэтому в начале работы алгоритма важно инициализировать стек элементами первого уровня - ещё перед заходом в основной цикл перебора стека
кстати, nextSibling() без указания имени ищет любой следующий тег этого же уровня (скорее всего тег будет тот, что идёт в реальном тексте XML , но на это не стоит полагаться, мне кажется - не знаю, что на этот счёт говорит стандарт. Я всегда предполагаю, что порядок выбора может быть случайным)
если указать имя предыдущего элемента, найдётся элемент с таким же именем:
node.nextSibling(node.nodeName());
Немного переделал вариант от lanz, так как его не работал.
+ без доп функции пока никак...
QList<QDomNode> MyClass::childNodeList(QDomNode parent)
{
QList<QDomNode> outList;
QDomNodeList tmpList = parent.childNodes();
for (int i = 0; i < tmpList.count(); ++i)
outList << tmpList.at(i);
return outList;
}
void MyClass::someClass()
{
QList<QDomNode> list = childNodeList(m_svgNode);
while (!list.empty()) {
QDomElement currElem = list.takeAt(0).toElement();
// stuff
list << childNodeList(currElem);
}
}
Это я конечно маху дал, думал что QDomNodeList это typedef вроде QObjectList.
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)