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

时间:2013-06-19 15:38:25

标签: c++ xml qt

我用QXmlStreamWriter创建了一个xml文件,然后我想在关闭xml文件之前每次添加一个块。 但是,我想要做的是使用startDocument将块添加到文件的末尾,所以在每次添加时我都有一个XML头,为此我在读取文档时出错,程序读取第一个块,当它进入第二个块时,它显示“xml声明不在文档的strat”这是我的文件:

<?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>

如你所见&lt; NUMERO_SLICE&gt;每次添加新参数时都会重复阻止。通常在&lt;之前添加该块。 / Fiche_Du_Patient&gt;但是我没有找到QXmlStreamWriter的方法(我是xml的初学者)我在网上搜索过,我一无所获。

是否存在,请添加&lt; NUMERO_SLICE&GT;每次都阻止?

亲切

2 个答案:

答案 0 :(得分:3)

我认为只有这样的黑客才能避免将完整的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 :(得分:0)

如果您选择继续使用QXmlStreamReader / Writer,则需要:

  1. 使用QXmlStreamReader
  2. 阅读内容
  3. 同时也写出QXmlStreamWriter
  4. 以下是您需要做的事情的示例。请记住,还有许多其他需要检查的案例,例如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>