Разбор XML с QXmlStreamReader

Я создал этот XML-файл с QXmlStreamWriter:

<?xml version="1.0" encoding="UTF-8"?>
<Draw>
<Input>
<Column title="A"/>
<Column title="B"/>
<Column title="C"/>
<Column title="D">
<item id="0">Bayer Leverkusen</item>
<item id="1">Benfica</item>
<item id="2">Villareal</item>
<item id="3">Montpellier</item>
</Column>
</Input>
</Draw>

Я хотел бы создать вектор строки, содержащий все элементы внутри тега Column title="D"Теперь я знаю, как создать QVector и как они соответствуют элементам внутри, я просто должен выяснить, как я могу сделать это, экстраполируя информацию из XML-файла.

Вы можете мне помочь?

1

Решение

Вы можете использовать QXmlStreamReader перебрать элементы XML и найти <Column title="D"> элемент. Как только вы нашли это, readNextStartElement() в сочетании skipCurrentElement() может использоваться для чтения всех его дочерних элементов.

Давайте предположим, что документ XML, который вы показали в своем экзамене, можно прочитать из xmlDocument объект. Извлечь все <item> элементы из <Column title="D"> Элемент с соответствующей проверкой ошибок, вы можете сделать следующее:

QXmlStreamReader xmlIterator(xmlDocument);
QVector<QString> output;

for(; !xmlIterator.atEnd(); xmlIterator.readNext()) {
if(isStartElementOfColumnD(xmlIterator)) {
while(xmlIterator.readNextStartElement()) {
if(isItemElement(xmlIterator))
output.append(xmlIterator.readElementText());
else
xmlIterator.skipCurrentElement();
}
}
}

if(xmlIterator.hasError())
qCritical() << "Error has occurred:" << xmlIterator.errorString();
else
qDebug() << output;

В приведенном выше примере я использовал два предиката, чтобы скрыть длинную и трудно читаемую проверку xmlIterator, Это следующие:

inline bool isStartElementOfColumnD(const QXmlStreamReader& xmlIterator) {
return xmlIterator.isStartElement() && xmlIterator.name() == "Column" &&
xmlIterator.attributes().value("title") == "D";
}
inline bool isItemElement(const QXmlStreamReader& xmlIterator) {
return xmlIterator.name() == "item" &&
xmlIterator.attributes().hasAttribute("id");
}

Пример результата:

QVector("Bayer Leverkusen", "Benfica", "Villareal", "Montpellier")
0

Другие решения

Я бы написал это следующим образом:

QVector<QString> store;

[..]
if (reader.readNextStartElement() && reader.name() == "Draw") {
while (reader.readNextStartElement() && reader.name() == "Input") {
while (reader.readNextStartElement()) {
QXmlStreamAttributes attr = reader.attributes();
if (reader.name() == "Column" && attr.value("title").toString() == "D") {
while(!(reader.isEndElement() && reader.name() == "Column")) {
if (reader.isStartElement() && reader.name() == "item") {
QString text = reader.readElementText();
store.append(text);
}
reader.readNext();
if (reader.hasError()) {
// Handle error.
QString msg = reader.errorString();
break;
}
}
} else {
reader.readNext();
}
}
}
} else {
reader.raiseError("Expected <Draw> element");
}
[..]
-1

По вопросам рекламы [email protected]