Структура xml:
<help>
<page id="page01">
<title>title of page01</title>
<message>text</message>
</page>
...
<page id="page99">
<title>title of page99</title>
<message>text</message>
</page>
</help>
QDomElement docElem;
docElem = doc.elementById("page01");
QDomNodeList lstNodes(docElem.childNodes()));
for (int n=0; n<lstNodes.count(), n++)
{
childElem = lstNodes.at(n)::toElement();
if (childElem.tagName == "message")
{
message = childElem.text();
}
}
Начну с того, что в приведенном Вами коде очень много ошибок, что очень неприятно при отладке. Надо быть поокуратнее.
QDomElement docElem;
QDomNodeList lstNodes(domDocument.elementsByTagName("page"));
for (int n=0; n<lstNodes.count(); n++)
{
QDomElement childElem = lstNodes.at(n).toElement();
if (childElem.attribute("id") == "page01")
{
QDomElement child = childElem.lastChild().toElement();
qDebug() << child.text();
}
}
Выдает ошибку
crosses initialization of ‘QDomNodeList lstNodes’
QDomElement childElem = lstNodes.at(n).toElement();
???
Я так понимаю, что childElem у Вас где-то уже объявлен.
Сделайте просто
childElem = lstNodes.at(n).toElement();
childElem ранее объявлен не был.
Замена строки не помогла, ошибка та же самая...
копируем куда-нибудь проект QTDIR/examples/xml/dombookmarks
В файле xbeltree.cpp ищем функцию bool XbelTree::read(QIODevice *device)
Что бы не мучаться, заменяем весь ее код, на следущий:
bool XbelTree::read(QIODevice *device)
{
QString errorStr;
int errorLine;
int errorColumn;
if (!domDocument.setContent(device, true, &errorStr, &errorLine,
&errorColumn)) {
QMessageBox::information(window(), tr("DOM Bookmarks"),
tr("Parse error at line %1, column %2:\n%3")
.arg(errorLine)
.arg(errorColumn)
.arg(errorStr));
return false;
}
QDomElement docElem;
QDomNodeList lstNodes(domDocument.elementsByTagName("page"));
for (int n=0; n<lstNodes.count(); n++)
{
QDomElement childElem = lstNodes.at(n).toElement();
if (childElem.attribute("id") == "page01")
{
QDomElement child = childElem.lastChild().toElement();
qDebug() << child.text();
}
}
return true;
}
<?xml version="1.0" encoding="UTF-8"?>
<help>
<page id = "page01">
<title>title of page01</title>
<message>text1</message>
</page>
<page id = "page99">
<title>title of page99</title>
<message>text2</message>
</page>
</help>
Есть решение немного по-изящнее:
QDomElement root = domDocument.documentElement();
QDomElement child = root.firstChildElement("page");
while (!child.isNull()) {
if (child.attribute("id") == "page01") {
QDomElement message = child.firstChildElement("message");
qDebug() << child.text();
}
child = child.nextSiblingElement("page");
}
qDebug() << message.text();
Kagami, спасибо большое! Мне как раз надо чтобы от положения элемента в xml не зависел его выбор.
Но ошибка так и остается:
expertsystem.cpp:174: error: jump to case label
expertsystem.cpp:163: error: crosses initialization of ‘QDomElement child’
expertsystem.cpp:162: error: crosses initialization of ‘QDomElement root’
expertsystem.cpp:161: error: crosses initialization of ‘QDomDocument domDocument’
Видимо у вас в коде есть что то вроде такого
switch (i) {
case 1:
int j = 1;
break;
case 2:
int j = 2;
break;
}
switch (i) {
int j;
case 1:
j = 1;
break;
case 2:
j = 2;
break;
}
void XmlStalker::SelfPortrait(const QDomNode &n, int rid, int id)
{
...
value= n.nodeValue().simplified();
...
t = n.toText();
data = t.data().simplified();
...
}
насчёт value() неправ, должно быть nodeValue()
Итак, currentId() содержит айдишник текущей страницы. Обработка нажатия на кнопку "Помощь" (только основное):
QString pageid = QString::number(currentId());
QDomDocument domDocument;
QDomElement root = domDocument.documentElement();
QDomElement help = root.firstChildElement("help");
QDomElement child = help.firstChildElement("page");
while (!child.isNull())
{
if (child.attribute("id") == pageid)
{
QDomElement mess = child.firstChildElement("message");
message = mess.text();
//message = pageid;
}
child = child.nextSiblingElement("page");
}
<?xml version="1.0" ?>
<!-- Help data -->
<help>
<page id="0">
<title>title0</title>
<message>message0</message>
</page>
<page id="1">
<title>title1</title>
<message><![CDATA[message1]]></message>
</page>
</help>
FladeX, У меня есть тестовая программа по которой я изучал QDOM, вот что она расказывает о твоём файле:
А какая область видимости у переменной message?
Только внутри функции. Используется для QMessageBox и все.
В приведенном выше кусочке вроде ошибок не видно. Было бы неплохо глянуть на весь код этой процедуры
Вот функция целиком:
void ExpertSystem::showHelp()
{
static QString lastHelpMessage;
QString message;
QDomDocument doc;
QFile file("/home/opensuse/qt/expertsystem/help.xml");
if (!file.exists())
{
QMessageBox::warning(this, QObject::trUtf8("Предупреждение"), QObject::trUtf8("Ошибка 001. Файл help.xml не существует"));
}
if (!file.open(QIODevice::ReadOnly))
{
QMessageBox::warning(this, QObject::trUtf8("Предупреждение"), QObject::trUtf8("Ошибка 002. Невозможно открыть файл help.xml"));
return;
}
if (!doc.setContent(&file))
{
QMessageBox::warning(this, QObject::trUtf8("Предупреждение"), QObject::trUtf8("Ошибка 003. Невозможно прочитать файл help.xml"));
file.close();
return;
}
doc.setContent(&file);
QString pageid = QString::number(currentId());
QDomDocument domDocument;
QDomElement root = domDocument.documentElement();
QDomElement help = root.firstChildElement("help");
QDomElement child = help.firstChildElement("page");
while (!child.isNull())
{
if (child.attribute("id") == pageid)
{
QDomElement mess = child.firstChildElement("message");
message = mess.text();
//message = pageid;
}
child = child.nextSiblingElement("page");
}
file.close();
//if (lastHelpMessage == message)
// message = tr("");
QMessageBox::information(this, QObject::trUtf8("Подсказка"), message);
lastHelpMessage = message;
}
Посидел десять минут, но раскусил этот орешек:
Спасибо за развернутый ответ! Теперь понятнее стало.
Однако, погоняв эту функцию, заметил, что условие
if (child.attribute("id") == pageid)
Из-за области видимости переменной. Если ее создавать в условии, то в его конце она будет удалена
Не совсем понял, какую переменную мы создаем в условии...
Перенес из цикла все что только можно было вынести - результат тот же (пустое модальное окно). Перенес вызов QMessageBox внутрь цикла - модальное окно вообще перестало вызываться.
А какие значение возвращает currentId() ?
Возвращает int.
Но я уже решил проблему:
Вместо этого:
QString pageid = "page" + QString("%1").arg(1,2,10,QChar('0'));
QString pageid = QString::number(currentId());
Если бы я заметил что в середине обсуждения у тебя поменялся xml-файл все решилось бы быстрее
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)