Скажем, у нас есть следующий XML-документ:
<root>
<options>
...
</options>
<children>
<child name="first">12345</child>
<child name="second">
<additionalInfo>abcd</additionalInfo>
</children>
</root>
Я хотел бы получить строковое представление "дочерних" узлов и добавить их в массив (я не хочу терять синтаксис XML, таким образом, .text () не опция). Например, первый ребенок был бы похож:
QString child = "<child name="first">12345</child>";
Я использовал следующий код получить элементы:
QDomDocument doc;
QDomElement element;
element = xml->documentElement();
if(element.isNull() == false)
{
element = element.firstChildElement("children");
if(element.isNull()) return;
element = element.firstChildElement("child");
while(element.isNull() == false)
{
doc = element.toDocument();
if(doc.isNull() == false)
{
// save string into array
array.append(doc.toString());
}
element = element.nextSiblingElement("child");
}
}
Проблема состоит в том, что doc.isNull всегда возвращается, ложь (похож, я не могу преобразовать элемент в документ). Есть ли какой-либо путь, как я могу выполнить это?
Править:
Я хотел бы добавить, что QString не обязателен здесь. В основном любой класс, который может позже использоваться для получения данных, в порядке (я буду сохранять эти узлы и использовать их для инициализации, другой возражает позже). Важная вещь состоит в том, что я должен смочь получить доступ к тем значениям, даже когда оригинал документа был уничтожен. Например, это это возможный сохранить те элементы непосредственно к некоторому массиву (например, QList), который может использоваться для доступа к ним позже.
Я добавлю ответ на свой вопрос. Не знаю почему, но похоже, что я пропустил следующую функцию в документации.
void QDomNode :: save (QTextStream & str, int indent) const
Он делает почти все, что мне нужно для преобразования узла в строку, например:
QString str;
QTextStream stream(&str);
QDomNode node = xml->documentElement().firstChildElement("child");
node.save(stream, 4 /*indent*/);
// process str
Поскольку вам нужен сам формат XML, вам не нужны QDomElement
или QDomDocument
. QDomElement
и QDomDocument
используются для получения данных, хранящихся в документах XML.
Вам просто нужен обычный обход файла.
Откройте файл с помощью
bool QFile::open ( OpenMode mode ) [virtual]
. Вы можете прочитать все содержимое файла с помощью,
QByteArray QIODevice::readAll ()
, который вы можете присвоить ему QString
.
Например,
QString entireContents = xmlFile->readAll();
Затем вы можете разделить все содержимое на основе символа новой строки \ n
, используя
QStringList QString::split ( const QString & sep, SplitBehavior behavior = KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive ) const
. Теперь каждый индекс соответствует каждой строке в XML-файле. Вы можете пройти по нему и получить желаемые интересующие линии.
Надеюсь, это поможет ...
Ну, я думаю, что вы не сможете сделать в точности то, что хотите, с помощью классов Qt XML, но должно быть возможно просто восстановить строку самостоятельно (возможно, не соответствующую оригиналу на 100%, но с тем же значением), основываясь на методах, которые предоставляют классы Qt XML.
EDIT:. Небольшой фрагмент кода, который может сделать эту вещь (не проверено):
QString domElementToRawXML(const QDomElement& elem)
{
QString head = "<"+elem.tagName();
QDomNamedNodeMap attrs = elem.attributes();
for(int i = 0; i<attrs.size(); ++i)
{
QDomAttr attr = attrs.item(i).toAttr();
head +=
QString::fromLatin1(" %0=\"%1\"")
.arg(attr.name())
.arg(attr.value());
}
head += ">";
return head + elem.text() + "</"+elem.tagName()+">";
}