Изменить значение QDomElement? - PullRequest
11 голосов
/ 20 июля 2011

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

У меня есть 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.

Мы будем рады любым предложениям, образцам кода, ссылкам.

Ответы [ 5 ]

18 голосов
/ 25 июля 2011

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

// 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();

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

4 голосов
/ 17 апреля 2014

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

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

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

2 голосов
/ 24 июля 2011

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

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

в

<?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();
1 голос
/ 25 июля 2011

Вот версия вашего кода, которая делает то, что вам нужно.Обратите внимание, как сказал Спрафф, ключ находится в поиске дочернего элемента узла "firstchild" типа text - там, где текст живет в 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's 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();
0 голосов
/ 20 июля 2011

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

...