Я создал этот 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-файла.
Вы можете мне помочь?
Вы можете использовать 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")
Я бы написал это следующим образом:
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");
}
[..]