Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Получить QDomNode из xml по имени
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Обработка XML
RazrFalcon
...
<example name="example text"/>
...
В XML куча вложений и элементов. Как найти элемент example, кроме как через рекурсивную функцию?
То есть найти его, где бы в xml он не находился.
Алексей1153
можно попробовать открыть файл как текст и найти строку "<example name="
RazrFalcon
Нее... нужен именно QDomNode, так как потом мне нужно будет получить список его дочерних элементов.
Алексей1153
если структура XML не меняется, либо меняется по твоему пожеланию, то ты всегда можешь пройти путь к нужному элементу. Ели же задача стоит в том, чтобы этот элемент искать в неизвестном месте, то кроме как обойти все ветки и найти его - наверное, никак

Цитата
QDomNodeList childNodes () const


вот этот метод тоже пригодится при поиске
Цитата
QDomNode QDomNode::namedItem ( const QString & name ) const
RazrFalcon
Сделал так. Работает.
...
findNode(name,mainNode.firstChild());
qDebug()<<findedNode.toElement().tagName(); // findedNode - глобальная переменная QDomNode findedNode;
...

void GuiInfo::findNode(const QString &name, const QDomNode &node)
{
  if (node.hasChildNodes()) {
    QDomNodeList tempNodeList = node.childNodes();
    for (int i = 0; i<tempNodeList.count(); ++i) {
      if (tempNodeList.at(i).toElement().tagName().contains(name))
        findedNode = tempNodeList.at(i); // когда я получу значение, нужно убить циклы все, как?
      else if (tempNodeList.at(i).hasChildNodes())
        findNode(name,tempNodeList.at(i));
    }
  }
}

Разве что не пойму, как остановить эту рекурсивную функцию.
Алексей1153
как-нибудь так

const QDomNode node GuiInfo::findNode(const QString &name, const QDomNode &node)
{
  if (node.hasChildNodes())
  {
    QDomNodeList tempNodeList = node.childNodes();
    for (int i = 0; i<tempNodeList.count(); ++i)
    {
      if (tempNodeList.at(i).toElement().tagName().contains(name))
      {
        findedNode = tempNodeList.at(i); // когда я получу значение, нужно убить циклы все, как?
        return findedNode;
      }
      else if (tempNodeList.at(i).hasChildNodes())
      {
        findNode(name,tempNodeList.at(i));
      }
    }
  }

  return QDomNode();
}


но за правильность не уверен, так как не пойму, используются тут ссылки на внешние переменные или локальные переменные. Вернул по значению
RazrFalcon
const QDomNode node GuiInfo::findNode
А можно этот момент объяснить?
const QDomNode GuiInfo::findNode
Это я бы еще понял, но что там делает node?

return QDomNode();
не пойму что возвращаем?
Алексей1153
"node" - это очепятка вкралась. В блокноте правил :D

"return QDomNode();"
- возвращаем пустой объект - ведь что-то всё равно нужно вернуть
RazrFalcon
Ааа! Все понял. Про "return QDomNode();" не знал.

Возвращает пустые...
Алексей1153
в отладчике гляди, где неправильно дело идёт
RazrFalcon
Оно создает 2-а GuiInfo::findNode, и ретурн убивает первый (дочерний), а второй (главный) возвращает QDomNode().
То есть функция успевает зайти сама в себя и убивается не вся, а только дочерня ее часть.

По этому я создал эту тему, так же было и до этого.
Алексей1153
made in the Notepad ))

попробуй

//рекурсивный поиск
bool GuiInfo::findNode(const QString &name, const QDomNode &node, const QDomNode& found)
{
    if(node.nodeName()==name)
    {
      found = node;
      return true;
    }

  if(node.hasChildNodes())
  {
    QDomNodeList tempNodeList = node.childNodes();
    for(int i = 0; i<tempNodeList.count(); i++)
    {
      if(findNode(name,tempNodeList.item(i),found))return true;
    }
  }

  return false;
}

//ищем
GuiInfo::F1()
{
  node=...;
  QDomNode found;
  if(findNode("aaaa", node, found))
  {
    //нашли - found
  }
}
RazrFalcon
Рабочий вариант:
//ищем
GuiInfo::F1()
{
QDomNode node;
if (findNode("name",mainNode,node))
  qDebug()<<"find!";
}

bool GuiInfo::findNode(const QString &name, const QDomNode &node, QDomNode &fnode)
{
  if (node.hasChildNodes()) {
    QDomNodeList tempNodeList = node.childNodes();
    for (int i = 0; i<tempNodeList.count(); ++i) {
      if (tempNodeList.at(i).toElement().tagName().contains(name)) {
        fnode = tempNodeList.at(i);
        return true;
      }
      else if (tempNodeList.at(i).hasChildNodes()) {
        if(findNode(name,tempNodeList.item(i),fnode))
          return true;
      }
    }
  }

  return false;
}
Алексей1153
RazrFalcon, в твоём варианте, в отличие от моего, если у искомого узла будут дети, то ты его не найдёшь
RazrFalcon
У меня все нашло. И с детьми и без.
Алексей1153
ну, нашлось, так нашлось.
DOGG
Может подойдет метод QDomNodeList QDomDocument::elementsByTagName ( const QString & tagname ) const?
RazrFalcon
Капец! Работает.
Сократил код в 100500 раз.
Спасибо!
DOGG
Пожалуйста! :)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.