PDA

View Full Version : XML writing problem



Shawn
22nd October 2007, 07:44
I used DOM to parse a XML file. I find a specified tag and add some childnodes under it. Then I called save() to convert the tree back to XML.
Pronlem is like this:
Original XML file:

<doc>
<quote>Ars longa vita brevis</quote>
<translation>Art is long, life is short</translation>
</doc>
After modified the tree in memory and called save():

<doc>
<quote>Ars longa vita brevis</quote>
<translation>Art is long, life is short</translation>
</doc>
<doc>
<quote>Ars longa vita brevis</quote>
<translation>Art is long, life is short</translation>
<translation2>Art is long, life is short</translation2>
</doc>

The original file is duplicated!
Any hint is appreciated!

wysota
22nd October 2007, 08:14
Could we see the code?

jpn
22nd October 2007, 08:17
Well, QDomNode::save() operates on a stream. If you first read from a stream and then write to it, writing continues where reading was left. You might want to consider re-opening the file as truncated (seeking to position 0 is not enough since new content could be shorter which would leave garbage at the end of the file).

Shawn
22nd October 2007, 09:16
the code is liek this:

QFile fout("Resources/file_out.xml");
QDomDocument doc_out;
QMap<QString, QString> IED_IPAdrr_Pair;

if (!doc_out.setContent(fout, true, &errorStr, &errorLine, &errorColumn)) {
QMessageBox::warning(0, QObject::tr("DOM Parser"),
QObject::tr("Parse error at line %1, "
"column %2:\n%3")
.arg(errorLine)
.arg(errorColumn)
.arg(errorStr));
return;
}

const int Indent = 4;
QDomNode root = doc_out.firstChild();
QDomNode node = findTag(root , "RemoteAddressList");
QMap<QString, QString>::const_iterator i = IED_IPAdrr_Pair.constBegin();
while (i != IED_IPAdrr_Pair.constEnd()) {
QDomText t2 = doc_out.createTextNode(i.key());
QDomText t3 = doc_out.createTextNode(i.value());

QDomElement e1 = doc_out.createElement("RemoteAddress");

QDomElement e2 = doc_out.createElement("AR_Name");
e2.appendChild(t2);

QDomElement e3 = doc_out.createElement("NetAddr");
e3.setAttribute("Type", "IPADRR");
e3.appendChild(t3);

e1.appendChild(e2);
e1.appendChild(e3);

node.appendChild(e1);

++i;
}

QTextStream out(fout);
doc_out.save(out, Indent);

here is the declaration of findTag():

QDomNode findTag(QDomNode &node, const QString &tag);
it find the specified tag name and return with the a QDomNode

Shawn
22nd October 2007, 09:25
Basically, I used QDomDocument::setContent(QIODevice * dev,...) to get a QDomDocument object tree in memory, then I modified this tree, then called void QDomNode::save ( QTextStream & str, int indent ) const to write this tree back to the QFile object.

The problem may exists that I need to "clear" the original file first.

hgedek
24th October 2007, 13:32
Actually I asked this question ago.I think there is no way for updating info in xml for now.you can only write all doc again.first delete old file(open as W mode) then write.

Shawn
24th October 2007, 13:35
Yes, that's also my thinking.

Actually this is exactly what I've done after posting my last thread. :-)