2011-07-19 90 views
11

我需要編輯QDomElement的文本 - 例如編輯QDomElement的值?

我有一個XML文件,其作爲內容 -

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

如何編輯的子元素<firstchild>的文字?

我看不出有任何的功能在Qt的4.7

EDIT1提供的QDomDocument的QDomElement類的描述 - 我加入了更多的細節。

我需要讀取,修改和保存一個xml文件。到該文件的格式如下 -

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

元素的值需要是edited.I代碼來讀取該XML文件是 -

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

QByteArray xmlData(xmlFile.readAll()); 

QDomDocument doc; 
doc.setContent(xmlData); 

//讀取必要的值

//寫回修改後的值?

注:我試圖將QDomElement轉換爲QDomNode並使用函數setNodeValue()。但是它不適用於QDomElement。

任何建議,代碼示例,鏈接,我們非常歡迎。

回答

18

這將做你想做的(你貼就會留在這裏代碼):

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

...和你都設置。你當然也可以寫一個不同的文件。在這個例子中,我只截斷了現有文件並覆蓋了它。

+0

這適用於輕微的修改。謝謝。 –

+1

@永遠的學習者:不要忘記了解賞金! – Goz

+3

實際上,裏面的文本是一個文本節點,所以你可以這樣做,如下所示:doc.documentElement()。firstChildElement(「firstchild」)。firstChild()。setNodeValue(「new text」); //注意額外的firstChild()查詢 – Petar

-2

上去一個抽象層次到QDomNodefirstchild是一個QDomText元素,因此您可以使用value()setValue(x)來處理文本本身。

+0

QDomNode :: firstChild返回QDomNode而不是QDomText。 –

+0

問題中的QDomNode *是* QDomText。檢查繼承樹。您在運行時檢查節點類型[並將其轉換](http://doc.qt.nokia.com/latest/qdomnode.html#toText) – spraff

+0

不,'firstchild'是'QDomElement'。它有一個孩子'QDomText'。我檢查了它。 – Lol4t0

1

是什麼問題。你想寫什麼樣的價值? 例如,休耕代碼這個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(); 
+0

setNodevalue函數僅適用於某些元素類型。在Qt文檔中查看'QString QDomNode :: nodeValue()const'方法。它們提供了setNodeValue適用的節點列表。我需要設置一個'QDomELement'的值。 –

+0

你錯了。正如你在我的例子中看到的那樣,'QDomElement'_不直接包含任何文本。但它包含'QDomText'元素,其中包含您的文本。如果'QDomElement'直接包含文本,當替換它時,您將擦除元素的所有子節點。 – Lol4t0

1

這裏是你的代碼的版本,那麼你需要什麼。請注意,正如spraff所說的,關鍵是找到文本類型的「firstchild」節點的子節點 - 這就是文本在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

這對我有用,當我改變閱讀「QDomText t = n.toText();」的行時「改爲讀取「QDomText t = n.firstChild()。toText();」。 – myk

3

當您想要更改節點內的文本時,只需使用更好更簡單的解決方案(類似於Lol4t0寫的)更新此文件。該「則firstChild」節點內的文本實際上變成一個文本節點,所以你想要做的是:

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

通知,將實際訪問文本節點,使您能夠更改值額外則firstChild()調用。這比創建新節點和替換整個節點要簡單得多,而且速度更快,侵入性更小。