Изменить значение QDomElement?

Мне нужно отредактировать текст QDomElement - Eg

У меня есть XML файл с его содержимым как

<root>    
    <firstchild>Edit text here</firstchild>
</root>

Как отредактировать текст дочернего элемента <firstchild>?

Я не вижу никаких функций в описаниях классов QDomElement классов QDomDocument, приведенных в Qt 4.7

Edit1 - Я добавляю более подробную информацию.

Мне нужно прочитать, изменить и сохранить xml файл. Формат файла следующий:

<root>    
    <firstchild>Edit text here</firstchild>
</root>

Значение элемента необходимо отредактировать. Код для чтения XML файла -

QFile xmlFile(".\\iWantToEdit.xml");
xmlFile.open(QIODevice::ReadWrite);

QByteArray xmlData(xmlFile.readAll());

QDomDocument doc;
doc.setContent(xmlData);

//Прочитайте необходимые значения

//записать обратно измененные значения?

Примечание. Я попытался передать QDomElement в QDomNode и использовать функцию setNodeValue(). Однако он не применим к QDomElement.

Любые предложения, примеры кода, ссылки были бы очень приветствуемыми.

Ответ 1

Это сделает то, что вы хотите (код, который вы опубликовали, останется таким, как есть):

// Get element in question
QDomElement root = doc.documentElement();
QDomElement nodeTag = root.firstChildElement("firstchild");

// create a new node with a QDomText child
QDomElement newNodeTag = doc.createElement(QString("firstchild")); 
QDomText newNodeText = doc.createTextNode(QString("New Text"));
newNodeTag.appendChild(newNodeText);

// replace existing node with new node
root.replaceChild(newNodeTag, nodeTag);

// Write changes to same file
xmlFile.resize(0);
QTextStream stream;
stream.setDevice(&xmlFile);
doc.save(stream, 4);

xmlFile.close();

... и все вы настроены. Конечно, вы могли бы написать и другой файл. В этом примере я просто усекал существующий файл и перезаписал его.

Ответ 2

Просто обновите это с помощью более простого и простого решения (похожего на Lol4t0), когда вы хотите изменить текст внутри node. Текст внутри "firstchild" node фактически становится текстом node, поэтому вы хотите:

...
QDomDocument doc;
doc.setContent(xmlData);
doc.firstChildElement("firstchild").firstChild().setNodeValue(‌​"new text");

обратите внимание на дополнительный вызов firstChild(), который фактически получит доступ к тексту node и позволит вам изменить значение. Это намного проще и, безусловно, быстрее и менее инвазивно, чем создание нового node и замена всего node.

Ответ 3

в чем проблема. Какие значения вы хотите написать? Например, принятый код преобразует этот xml

<?xml version="1.0" encoding="UTF-8"?>
<document>
    <node attribute="value">
        <inner_node inner="true"/>
        text
    </node>
</document>

to

<?xml version='1.0' encoding='UTF-8'?>
<document>
    <new_amazing_tag_name attribute="foo">
        <bar inner="true"/>new amazing text</new_amazing_tag_name>
</document>

код:

QFile file (":/xml/document");
file.open(QIODevice::ReadOnly);
QDomDocument document;
document.setContent(&file);
QDomElement documentTag = document.documentElement();
qDebug()<<documentTag.tagName();

QDomElement nodeTag = documentTag.firstChildElement();
qDebug()<<nodeTag.tagName();
nodeTag.setTagName("new_amazing_tag_name");
nodeTag.setAttribute("attribute","foo");
nodeTag.childNodes().at(1).setNodeValue("new amazing text");

QDomElement innerNode = nodeTag.firstChildElement();
innerNode.setTagName("bar");
file.close();

QFile outFile("xmlout.xml");
outFile.open(QIODevice::WriteOnly);
QTextStream stream;
stream.setDevice(&outFile);
stream.setCodec("UTF-8");
document.save(stream,4);
outFile.close();

Ответ 4

Вот версия вашего кода, которая делает то, что вам нужно. Обратите внимание, что, как сказал spraff, ключ - найти дочерний элемент "firstchild" node текста типа - то, где текст живет в DOM.

   QFile xmlFile(".\\iWantToEdit.xml");
    xmlFile.open(QIODevice::ReadWrite);

    QByteArray xmlData(xmlFile.readAll());

    QDomDocument doc;
    doc.setContent(xmlData);

    // Get the "Root" element
     QDomElement docElem = doc.documentElement();

    // Find elements with tag name "firstchild"
    QDomNodeList nodes = docElem.elementsByTagName("firstchild"); 

    // Iterate through all we found
    for(int i=0; i<nodes.count(); i++)
    {
        QDomNode node = nodes.item(i);

        // Check the node is a DOM element
        if(node.nodeType() == QDomNode::ElementNode)
        {
            // Access the DOM element
            QDomElement element = node.toElement(); 

            // Iterate through it children
            for(QDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling())
            {
                // Find the child that is of DOM type text
                 QDomText t = n.toText();
                 if (!t.isNull())
                 {
                    // Print out the original text
                    qDebug() << "Old text was " << t.data();
                    // Set the new text
                    t.setData("Here is the new text");
                 }
            }
        }
    }

    // Save the modified data
    QFile newFile("iEditedIt.xml");
    newFile.open(QIODevice::WriteOnly);
    newFile.write(doc.toByteArray());
    newFile.close();

Ответ 5

Поднимите уровень абстракции до QDomNode. firstchild является элементом QDomText, поэтому вы можете получить value() и setValue(x) для работы с самим текстом.