Преобразование QDomElement в класс QString / Container - PullRequest
9 голосов
/ 14 июля 2010

Допустим, у нас есть следующий 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 всегда возвращает false (похоже, я не могу преобразовать элемент в документ).Есть ли способ, как я могу это сделать?

Редактировать:

Я хотел бы добавить, что QString здесь не является обязательным.В принципе, любой класс, который впоследствии можно будет использовать для извлечения данных, в порядке (я сохраню эти узлы и позже буду использовать их для инициализации других объектов).Важно то, что я должен иметь возможность доступа к этим значениям, даже если исходный документ был уничтожен. Например, можно сохранять эти элементы непосредственно в некотором массиве (например, QList), который можно использовать для доступа к ним позже.

Ответы [ 3 ]

14 голосов
/ 27 июля 2010

Я добавлю ответ на свой вопрос. Не знаю почему, но похоже, что я пропустил следующую функцию в документации.

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
0 голосов
/ 14 июля 2010

Ну, я думаю, что вы не можете делать точно то, что вы хотите с классами 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()+">";
}
0 голосов
/ 14 июля 2010

Поскольку вам нужен сам формат 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. Вы можете пройти через него и получить нужные линии интереса.

Надеюсь, это поможет ...

...