PDA

View Full Version : Problem in editing xml file through Dom parser.



Niamita
16th September 2011, 07:35
Hi all

i am in a trouble. My xml file is not edit right. Whem i am editing the file the contents to be edit are written in file with the rest data of file again. I am using Dom for reading and writing xml.

My code is


void HomeWindow::create_xml_file()
{
QFile *file = new QFile("E:/new.txt");
if(!edit_flag){ /// craeting the file and write in it in this condition
const int Indent = 4;
int id_value;
static QDomDocument doc;
static QDomElement root,root1;
QDomElement statement, action_node, condition_node;
QDomText id_text;
root = doc.createElement("root");

if(!file->exists())
{
file->open(QIODevice::WriteOnly);
QDomElement id = doc.createElement("id");
id_text = doc.createTextNode("0");
root.appendChild(id);
id.appendChild(id_text);
doc.appendChild(root);
}
else
{
file->open(QFile::ReadWrite);
doc.setContent(file);
root1 = doc.documentElement();
QDomElement node = root1.firstChildElement("id");
QString id_string = node.text();
id_value = id_string.toInt();
QDomElement new_id_node = doc.createElement(QString("id"));
QDomText new_id_Text = doc.createTextNode(QString::number(++id_value));
new_id_node.appendChild(new_id_Text); // replace existing node with new node
root1.replaceChild(new_id_node, node);
statement = doc.createElement("statement");
condition_node = doc.createElement("condition");
action_node = doc.createElement("action");
QDomText condition_text = doc.createTextNode(condition_text_edit->toPlainText());
QDomText action_text = doc.createTextNode(action_text_edit->toPlainText());
statement.setAttribute("id", id_value);
statement.appendChild(condition_node);
statement.appendChild(action_node);
condition_node.appendChild(condition_text);
action_node.appendChild(action_text);
root1.appendChild(statement);
file->seek(0);
static int i =1;
table->setRowCount(i);
QTableWidgetItem *item_id = new QTableWidgetItem(QString::number(id_value));
QTableWidgetItem *item_condition = new QTableWidgetItem(condition_text_edit->toPlainText());
QTableWidgetItem *item_action = new QTableWidgetItem(action_text_edit->toPlainText());
int row = i;
row = --row;
table->setItem(row, 0, item_id);
table->setItem(row, 1, item_condition);
table->setItem(row, 2, item_action);
i++;
condition_text_edit->clear();
action_text_edit->clear();
}
QTextStream out(file);
doc.save(out, Indent);
if(file->error())
qDebug()<<"error"<<file->errorString();
}
else{ ///////edit the file
const int indent =8;
QDomDocument doc;
file->open(QFile::ReadWrite);
doc.setContent(file);
QDomElement root_edit = doc.documentElement();
QDomNode node = root_edit.firstChild();
while(!node.isNull())
{
if (node.toElement().tagName() == "statement"){
if(string_id == node.toElement().attribute("id"))
{
QDomElement statement = doc.createElement("statement");
statement.setAttribute("id", string_id);
QDomElement condition_node = doc.createElement("condition");
QDomElement action_node = doc.createElement("action");
QDomText condition_text = doc.createTextNode(condition_text_edit->toPlainText());
QDomText action_text = doc.createTextNode(action_text_edit->toPlainText());
statement.appendChild(condition_node);
statement.appendChild(action_node);
condition_node.appendChild(condition_text);
action_node.appendChild(action_text);
root_edit.replaceChild(statement, node.toElement());
break;
}
}
node = node.nextSibling();
}
QTextStream out(file);
doc.save(out, indent);
QTableWidgetItem *item_id = new QTableWidgetItem(string_id);
QTableWidgetItem *item_condition = new QTableWidgetItem(condition_text_edit->toPlainText());
QTableWidgetItem *item_action = new QTableWidgetItem(action_text_edit->toPlainText());
table->setItem(row_index, 0, item_id);
table->setItem(row_index, 1, item_condition);
table->setItem(row_index, 2, item_action);
condition_text_edit->clear();
action_text_edit->clear();
edit_flag = false;
}
}

My xml file is looking like following

<root>
<id>3</id>
<statement id="1">
<condition>Digital Input Equals to END</condition>
<action>Analog Output Equals to END</action>
</statement>
<statement id="2">
<condition>Digital Input Equals to END</condition>
<action>Analog Output Equals to END</action>
</statement>
<statement id="3">
<condition>Digital Input Equals to END</condition>
<action>Analog Output Equals to END</action>
</statement>
</root>
tput Equals to END</action>
</statement>
<statement id="2">
<condition>Digital Input Equals to END</condition>
<action>gffjryjuuyd</action>
</statement>
</root>
<root>
<id>3</id>
<statement id="1">
<condition>Digital Input Equals to END</condition>
<action>Analog Output Equals to END</action>
</statement>
<statement id="2">
<condition>Digital Input Equals to END</condition>
<action>Analog Output Equals to END</action>
</statement>
<statement id="3">
<condition>Digital Input Equals to END</condition>
<action>gjkghk</action>
</statement>
</root>


Please guide me where i am wrong.
Waiting for quick reply.
Thanks.

wysota
16th September 2011, 23:18
If a file is 10 bytes long and you seek to the beginning and write 8 bytes, the file will remain to be 10 bytes long -- you will only modify the first 8 bytes, leaving the last two unchanged. If you want to discard the remaining bytes, you need to truncate the file.

Niamita
19th September 2011, 04:50
but i did not seek the file at the time of editing. Have you look at the xml file which generate after editing it.
Please give me some sample code.
Thanks.

wysota
19th September 2011, 11:32
I have already said everything I had to say, you have all info you need, just make proper use of it -- this is not kindergarden. Analyze your own code and reach your own conclusions. I can only repeat -- if you want to have the file be shorter than it was before, you need to truncate the file. This is general programming knowledge, nothing related to Qt or even C++.

ChrisW67
20th September 2011, 08:55
but i did not seek the file at the time of editing.
Sure you did...


root1.appendChild(statement);
file->seek(0);
static int i =1;
table->setRowCount(i);


The whole approach needs revision IMHO. Assuming the XML file is fairly small, the process is:

Read the whole document in the DOM from disc or create an "empty" DOM document if no file exists yet
Create/modify the document in the DOM using the relevant methods and whatever UI
Write the whole DOM document back to disc overwriting the old file if one exists.

No fiddling about with read/write files or trying to update in-situ. You should be able to draw solid dividing lines between the three elements.

wysota
20th September 2011, 09:02
...and truncate the file if you intend to write less than the previous content of the file.