【问题标题】:Modify an XML file QXMLStreamReader/Writer修改一个 XML 文件 QXMLStreamReader/Writer
【发布时间】:2017-08-22 09:55:46
【问题描述】:

我正在使用QXMLStreamReaderQXMLStreamWriter 来读取和写入文件。

但我无法找到一种可以修改 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();

现在我想在现有的 xml 文件中再添加一个 &lt;LIGHT1&gt;,那么如何在 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

【问题讨论】:

  • 根据post,单个设备不可能有多个流。
  • 你在 while 循环中关闭了输入文件

标签: c++ qt


【解决方案1】:

您可以使用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;
}

【讨论】:

  • 谢谢,我想在这些情况下使用QDomDocument 是唯一的解决方案。
  • @arqam 不仅如此。您还可以在读取原始 XML 时将新 XML 写入内存缓冲区或临时文件,然后在完成后将原始 XML 替换为新的。但是,如果 XML 小到可以放入内存(例如,在 PC 上最多几百兆字节),那么使用 DOM 会更好。
猜你喜欢
  • 1970-01-01
  • 2015-06-28
  • 2013-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-20
  • 2021-12-31
  • 1970-01-01
相关资源
最近更新 更多