1

我用 QXmlStreamWriter 创建了一个 xml 文件,然后我想在每次关闭 xml 文件之前添加一个块。但是,我要做的是使用 startDocument 将块添加到文件的末尾,所以在每次添加时我都有一个 XML 标头,为此我在读取文档时出错,程序读取第一个块并当它进入第二个块时,它显示“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> 块的方法?

亲切地

4

2 回答 2

3

我认为只有这种 hack 才能避免将完整的 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,但格式输出不是最佳的(丢失了漂亮的缩进)。更好的方法是解析最后一个标签,而不用硬编码。

于 2013-06-19T17:14:24.170 回答
0

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

  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>
于 2013-06-19T17:00:28.500 回答