如何使用QXmlStreamWriter在XML文件中添加节点?

问题描述:

我用QXmlStreamWriter创建了一个xml文件,然后我想在关闭xml文件之前每次添加一个块。 但是,我想要做的是将块添加到文件的结尾,并附带一个startDocument,因此在每一个添加中我都有一个XML头,为此我在读取文档时出错,程序读取第一个块当它进入到第二块,它让我“不是在文件STRAT XML声明:”这是我的文件:如何使用QXmlStreamWriter在XML文件中添加节点?

<?xml version="1.0" encoding="UTF-8"?> 
<Fiche_Du_Patient> 
<INFORMATIONS_DU_PATIENT> 
<Hopital>a </Hopital> 
    <Num_dossier>b</Num_dossier> 
    <Nom_et_prenom>c</Nom_et_prenom> 
    <Date_de_naissance>11111</Date_de_naissance> 
    <Sex>F </Sex> 
    <Age>26</Age> 
    <Date_examen>22222</Date_examen> 
    <Medecin_traitant></Medecin_traitant> 
    <Rapport></Rapport> 
</INFORMATIONS_DU_PATIENT> 
<NUMERO_SLICE> 
    <Num_Slice>1</Num_Slice> 
    <COORDONEES> 
    <X1>7.32896</X1> 
    <Y1>10.6362</Y1> 
    <X2>8.96937</X2> 
    <Y2>9.28687</Y2> 
    </COORDONEES> 
    <DISTANCE> 
    <Distance_en_cm>2.1241</Distance_en_cm> 
    </DISTANCE> 
    <ANGLE> 
    <Angle>7</Angle> 
    </ANGLE> 
</NUMERO_SLICE> 
</Fiche_Du_Patient> 
<?xml version="1.0" encoding="UTF-8"?> 
    <NUMERO_SLICE> 
    <Num_Slice>2</Num_Slice> 
    <COORDONEES> 
    <X1>7.80521</X1> 
    <Y1>10.3452</Y1> 
    <X2>9.49854</X2> 
    <Y2>9.525</Y2> 
    </COORDONEES> 
    <DISTANCE> 
    <Distance_en_cm>1.88152</Distance_en_cm> 
    </DISTANCE> 
    <ANGLE> 
    <Angle>1</Angle> 
    </ANGLE> 
</NUMERO_SLICE> 
<?xml version="1.0" encoding="UTF-8"?> 
    <NUMERO_SLICE> 
    <Num_Slice>3</Num_Slice> 
    <COORDONEES> 
    <X1>6.69396</X1> 
    <Y1>10.8215</Y1> 
    <X2>9.26042</X2> 
    <Y2>9.47208</Y2> 
    </COORDONEES> 
    <DISTANCE> 
    <Distance_en_cm>2.89957</Distance_en_cm> 
    </DISTANCE> 
    <ANGLE> 
    <Angle>25</Angle> 
    </ANGLE> 
    </NUMERO_SLICE> 

这种方法是错误的,我想要得到的是如下:

<?xml version="1.0" encoding="UTF-8"?> 
<Fiche_Du_Patient> 
<INFORMATIONS_DU_PATIENT> 
    <Hopital>a </Hopital> 
    <Num_dossier>b</Num_dossier> 
    <Nom_et_prenom>c</Nom_et_prenom> 
    <Date_de_naissance>11111</Date_de_naissance> 
    <Sex>F </Sex> 
    <Age>26</Age> 
    <Date_examen>22222</Date_examen> 
    <Medecin_traitant></Medecin_traitant> 
    <Rapport></Rapport> 
</INFORMATIONS_DU_PATIENT> 
<NUMERO_SLICE> 
    <Num_Slice>1</Num_Slice> 
    <COORDONEES> 
     <X1>7.32896</X1> 
     <Y1>10.6362</Y1> 
     <X2>8.96937</X2> 
     <Y2>9.28687</Y2> 
    </COORDONEES> 
    <DISTANCE> 
     <Distance_en_cm>2.1241</Distance_en_cm> 
    </DISTANCE> 
    <ANGLE> 
     <Angle>7</Angle> 
    </ANGLE> 
</NUMERO_SLICE> 
<NUMERO_SLICE> 
<Num_Slice>2</Num_Slice> 
<COORDONEES> 
    <X1>7.80521</X1> 
    <Y1>10.3452</Y1> 
    <X2>9.49854</X2> 
    <Y2>9.525</Y2> 
</COORDONEES> 
<DISTANCE> 
    <Distance_en_cm>1.88152</Distance_en_cm> 
</DISTANCE> 
<ANGLE> 
    <Angle>1</Angle> 
</ANGLE> 
</NUMERO_SLICE> 
<NUMERO_SLICE> 
<Num_Slice>3</Num_Slice> 
<COORDONEES> 
    <X1>6.69396</X1> 
    <Y1>10.8215</Y1> 
    <X2>9.26042</X2> 
    <Y2>9.47208</Y2> 
</COORDONEES> 
<DISTANCE> 
    <Distance_en_cm>2.89957</Distance_en_cm> 
</DISTANCE> 
<ANGLE> 
    <Angle>25</Angle> 
</ANGLE> 
</NUMERO_SLICE> 
</Fiche_Du_Patient> 

正如你所看到的< NUMERO_SLICE>块每增加一个新参数就重复一次。通常情况下,该块添加在</Fiche_Du_Patient>之前,但我还没有找到QXmlStreamWriter(我是xml中的初学者)的一种方式。我搜索了网络,但我对此没有任何发现。

是否存在请添加< NUMERO_SLICE>块每次之前?

亲切

+0

注意:我使用QXmlStreamWriter QXmlStreamReader,并且我有一个dom链接问题 – Clara

我认为,只有这个黑客能够避免读取完整的XML内存和重写:

{ 
    QString path("/home/carlo/test/x.xml"); 
    QString ctag = "</Fiche_Du_Patient>\n"; 

    QFile file(path); 
    qint64 s = file.size(); 
    if (s > 0) { 
     file.open(QFile::ReadWrite); 
     if (file.seek(s - ctag.length())) 
      Q_ASSERT(file.pos() == s - ctag.length()); 

    } else 
     file.open(QFile::WriteOnly); 

    QXmlStreamWriter xmlWriter(&file); 
    xmlWriter.setAutoFormatting(true); 
    xmlWriter.setAutoFormattingIndent(2); 

    if (s == 0) { 
     xmlWriter.writeStartDocument(); 
     xmlWriter.writeStartElement("Fiche_Du_Patient"); 
    } 

    xmlWriter.writeStartElement("NUMERO_Patient"); 
    xmlWriter.writeTextElement("Num_Patient", "123"); 
    xmlWriter.writeTextElement("Nom_et_prenom", s > 0 ? "appending" : "creating"); 
    xmlWriter.writeTextElement("Date_de_naissance", s > 0 ? "more date" : "first date"); 
    xmlWriter.writeEndElement(); 

    if (s == 0) { 
     xmlWriter.writeEndElement(); 
     xmlWriter.writeEndDocument(); 
    } 
    else 
     QTextStream(&file) << ctag; 
} 

这产生正确的XML,但格式输出不是最佳的(漂亮的缩进丢失)。更好的方法是解析最后的标签,而不用硬编码。

+1

谢谢谢谢,问题就解决了:) – Clara

如果你选择继续QXmlStreamReader /作家,你将需要:

  1. 使用QXmlStreamReader
  2. 虽然也写出来QXmlStreamWriter

阅读内容下面是一个例子,如果你需要做什么。请记住,有来检查的一些其他情况下的,像isComment(),复制属性等:

QString xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" 
       "<data>" 
       "<value>1</value>" 
       "<value>2</value>" 
       "</data>"; 

QString out; 
QXmlStreamWriter writer(&out); 

QXmlStreamReader reader(xml); 
while(!reader.atEnd()) 
{ 
    if(reader.isStartDocument()) 
    writer.writeStartDocument(); 

    if(reader.isStartElement()) 
    { 
    writer.writeStartElement(reader.name().toString()); 

    // New elements are appended here 
    if(reader.name() == "data") 
    { 
     writer.writeStartElement("newValue"); 
     writer.writeCharacters("newValue"); 
     writer.writeEndElement(); 
    } 
    } 

    if(reader.isCharacters()) 
    writer.writeCharacters(reader.text().toString()); 

    if(reader.isEndElement()) 
    writer.writeEndElement(); 

    if(reader.isEndDocument()) 
    writer.writeEndElement(); 

    reader.readNext(); 
} 

qDebug() << out; 

输出(格式化):

<?xml version="1.0"?> 
<data> 
    <newValue>newValue</newValue> 
    <value>1</value> 
    <value>2</value> 
</data> 
+0

感谢您的回答,但是在您的代码中它缺少像这样的文件的打开模式:if(File.Open(QFile :: ReadOnly | QFile :: Text)!)? – Clara

+0

=)。我理解你的问题是关于如何使用流读/写器类将新内容添加到XML数据。如果你想在QtDocumentation(网站上或通过QtCreator)上打开一个文件来查看QFile和QFileDialog,那么QString filename = QFileDialog :: ....; QFile文件(文件名); file.open(); – Huy

+0

@惠012 我收到以下错误: 'QIODevice :: write(QFile,“/Users/arqam/Desktop/XMLGenrator/input/zzzz.xml”):设备未打开 QIODevice :: read(QFile “/Users/arqam/Desktop/XMLGenrator/input/zzzz.xml”):设备@Huy我使用以下不open' – arqam