PDA

View Full Version : Use QXmlStreamWriter to modify existing elements



rhf417
19th June 2009, 23:16
I have a XML file as below:

<?xml version="1.0" encoding="UTF-8"?>
<content>
<calibrationBoard>
</calibrationBoard>
<calibrationOptions>
<camera value="0"/>
</calibrationOptions>
</content>

At runtime, I need to change the value of camera from "0" to "1".

How can I use QXmlStreamWriter to achieve this purpose? I only find out how to create new elements with QXmlStreamWriter, but I do not know how to modify existing elements with it.

Lykurg
20th June 2009, 00:13
With QXmlStreamWriter you can only write the whole document, inclusive the chanced value. But if you want to chance singe values without writing the whole document each time you have to use QDomDocument.

rhf417
23rd June 2009, 23:26
I use the following code to change the value of camera from "0" to "1", but the content of the xml file is not updated at all. Do I miss something?

--------------------------------------------------------------------------------------
QFile file;
file.setFileName("autocal.xml");
file.open(QIODevice::ReadWrite | QIODevice::Text);

QDomDocument doc("autocal");
doc.setContent(file)

QDomNodeList list = doc.elementsByTagName("calibrationOptions");
QDomNode parent = list.at(0);
QDomNode n = parent.firstChild();
if (n.isElement() && n.nodeName()=="camera")
{
QDomElement e = n.toElement();
e.setAttribute("value", "1");
}

file.close();

nish
24th June 2009, 02:44
the file is loaded in memory and changes are done in memory... to save the changes back in file just open the same file with writeonly(to erase old contents) and then save

void QDomNode::save ( QTextStream & str, int indent ) const

Lykurg
24th June 2009, 10:14
the file is loaded in memory and changes are done in memory... to save the changes back in file just open the same file with writeonly(to erase old contents) and then save

void QDomNode::save ( QTextStream & str, int indent ) const

That's principal right, but I guess you want to read the value somewhere else in your program. So every time open, save, read in elsewhere is not very good. Therefore only create one instance and pass a pointer of the QDomDocument to the needed classes, or use a singleton approach.

nish
24th June 2009, 10:22
ya.. i was just explaning the process.. ofcourse the read n write should be once.

rhf417
24th June 2009, 16:27
Thanks. The following code does update the xml file now. However, it duplicates the content.

QFile file;
file.setFileName("autocal.xml");
file.open(QIODevice::ReadWrite | QIODevice::Text);

QDomDocument doc("autocal");
doc.setContent(file);

//do some reading here

QDomNodeList list = doc.elementsByTagName("calibrationOptions");
QDomNode parent = list.at(0);
QDomNode n = parent.firstChild();
if (n.isElement() && n.nodeName()=="camera")
{
QDomElement e = n.toElement();
e.setAttribute("value", "1");
}

QTextStream stream(file);
doc.save(stream, 4);

file.close();

--------------------------------------------------------------------------------------


Do I have to open the file twice like below (first time readonly, second time writeonly)?

QFile file;
file.setFileName("autocal.xml");
file.open(QIODevice::ReadOnly | QIODevice::Text);

QDomDocument doc("autocal");
doc.setContent(file);
file.close();

//do some reading here

QDomNodeList list = doc.elementsByTagName("calibrationOptions");
QDomNode parent = list.at(0);
QDomNode n = parent.firstChild();
if (n.isElement() && n.nodeName()=="camera")
{
QDomElement e = n.toElement();
e.setAttribute("value", "1");
}

file.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream stream(file);
doc.save(stream, 4);
file.close();

Lykurg
24th June 2009, 16:32
Do I have to open the file twice like below (first time readonly, second time writeonly)?

No you can also use QIODevice::setOpenMode().

nish
25th June 2009, 03:23
what happened?? is it working or not?