2017-08-22 110 views
2

我正在使用QXMLStreamReaderQXMLStreamWriter来读取和写入文件。修改XML文件QXMLStreamReader/Writer

,但我没能找到一种方法,这样我可以修改XML,例如考虑这个XML:

<?xml version="1.0"?> 
<LAMPS> 
    <LIGHT1> 
     <State>statevalue</State> 
     <Room>roomvalue</Room> 
     <Potencial>potencialvalue</Potencial> 
    </LIGHT1> 
</LAMPS> 

这是使用下面的代码写的:

QFile file(filename); 
file.open(QIODevice::WriteOnly); 

QXmlStreamWriter xmlWriter(&file); 
xmlWriter.setAutoFormatting(true); 
xmlWriter.writeStartDocument(); 

xmlWriter.writeStartElement("LAMPS"); 

xmlWriter.writeStartElement("LIGHT1"); 
xmlWriter.writeTextElement("State", "statevalue"); 
xmlWriter.writeTextElement("Room", "roomvalue"); 
xmlWriter.writeTextElement("Potencial", "potencialvalue"); 
xmlWriter.writeEndElement(); 
xmlWriter.writeEndElement(); 
file.close(); 

现在我想要将一个<LIGHT1>添加到EXISTING XML文件中,那么在QT中如何做到这一点?

我做了以下内容:

 //filename = my file path 
    QFile file(filename); 
    file.open(QIODevice::ReadWrite); 
    QXmlStreamWriter xmlWriter(&file); 
    QXmlStreamReader xmlReader; 
    xmlReader.setDevice(&file); 
    xmlWriter.setAutoFormatting(true); 
    while(!xmlReader.atEnd()){ 
     if(xmlReader.isStartDocument()) 
      xmlWriter.writeStartDocument(); 
     if(xmlReader.isStartElement()){ 
      xmlWriter.writeStartElement(xmlReader.name().toString()); 
      if(xmlReader.name()=="LAMPS"){ 
       xmlWriter.writeStartElement("Arqam"); 
       xmlWriter.writeTextElement("Arqam","Lucid Dreamer"); 
       xmlWriter.writeEndElement(); 
      } 
     } 
     if(xmlReader.isEndElement()) 
      xmlWriter.writeEndElement(); 
     if(xmlReader.isEndDocument()) 
      xmlWriter.writeEndDocument(); 
     xmlReader.readNext(); 
     file.close(); 

而且我收到以下错误:

QIODevice::write (QFile, "/Users/arqam/Desktop/XMLGenrator/input/zzzz.xml"): device not open 
QIODevice::read (QFile, "/Users/arqam/Desktop/XMLGenrator/input/zzzz.xml"): device not open 
+0

根据该[柱](https://stackoverflow.com/questions/11710598/reading-the-same-file-with-several-different-streams-in-qt)它是不可能的对于单个设备有多个流。 – piarston

+0

您正在关闭while循环中的输入文件 –

回答

2

您可以使用QDomDocument存储来自XML内容。您可以创建新的孩子,标签,属性。

#include <QXmlStreamReader> 
#include <QXmlStreamWriter> 
#include <QFile> 
#include <QDomElement> 
#include <QDomDocument> 
#include <QDomText> 
#include <QTextStream> 

int main() 
{ 
    QFile file("test.xml"); 
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) 
    { 
     qDebug() << "Failed to open file"; 
     return 0; 
    } 
    QDomDocument document; 
    if (!document.setContent(&file)) 
    { 
     qDebug() << "failed to parse file"; 
     file.close(); 
     return 0; 
    } 

    file.close(); 

    QDomElement docEle = document.documentElement(); 
    QDomNodeList elements = docEle.elementsByTagName("LAMPS"); 

    QDomElement light1 = document.createElement("LIGHT1"); 
    QDomElement state = document.createElement("State"); 
    QDomText nextNode = document.createTextNode("State"); 
    state.appendChild(nextNode); 
    light1.appendChild(state); 
    docEle.appendChild(light1); 

    QFile outFile("test-result.xml"); 
    if(!outFile.open(QIODevice::WriteOnly | QIODevice::Text)) 
    { 
     qDebug("Failed to open file for writing."); 
     return 0; 
    } 

    QTextStream stream(&outFile); 
    stream << document.toString(); 

    outFile.close(); 
    return 0; 
} 
+0

谢谢,我想'QDomDocument'是这些情况下唯一的解决方案。 – arqam

+0

@arqam不只是方法。您也可以在读取原稿的同时将新的XML写入内存缓冲区或临时文件,然后在原始文件完成后用新文件替换原件。但是,如果XML足够小以适应内存(比如PC上至多有几百兆字节),那么使用DOM就更好了。 – hyde