I have an application that builds a left menu that is based on a tree Qt component. In order to load it I need to parse a XML file. The XML file looks like:
<comandos>
<categoria>
<nome>Cupom fiscal</nome>
<comando>
<nome>01 - Abrir Cupom Fiscal</nome>
<env>3</env>
<rec>4</rec>
<desc>CNPJ / CPF : </desc>
<desc>Nome : </desc>
<desc>Endereco: </desc>
</comando>
</categoria>
</comandos>
I can actually read this XML using QtDOM.
QDomDocument doc( "ComandosML" );
QFile file( "comandos.xml" );
int r = 0;
datafields.clear();
receFields.clear();
categories.clear();
if( !file.open( QIODevice::ReadOnly ) )
return -1;
if( !doc.setContent( &file ) )
{
file.close();
return -2;
}
// Ok we are ready to parse DOM
QDomElement root = doc.documentElement();
if( root.tagName() != "comandos" )
return -3;
QDomNode n = root.firstChild();
while( !n.isNull() )
{
QDomElement e = n.toElement();
if( !e.isNull() )
{
if( e.tagName() == "categoria" )
{
QDomNode cat = n.firstChild();
while( !cat.isNull() )
{
QDomElement CatName = cat.toElement();
if ( CatName.tagName() == "nome")
{
QString s = CatName.text();
if ( s != "")
{
categories.push_back(s);
item = new QStandardItem( (s) );
item->setEditable(false);
}
}
if ( CatName.tagName() == "comando")
{
QDomNode params = cat.firstChild();
QString qdCmd;
int env = 0;
int rec = 0;
Categories Desc;
while ( !params.isNull())
{
QDomElement ParamName = params.toElement();
if ( ParamName.tagName() == "nome")
{
qdCmd = ParamName.text();
child = new QStandardItem( (qdCmd) );
child->setEditable( false );
child->setDragEnabled(false);
item->appendRow( child );
}
else
if ( ParamName.tagName() == "env")
{
env = ParamName.text().toInt();
}
else
if ( ParamName.tagName() == "rec")
{
rec = ParamName.text().toInt();
}
else
if ( ParamName.tagName() == "desc")
{
Desc.push_back(ParamName.text());
}
params = params.nextSibling();
}
datafields.insert(pair<QString,int>( qdCmd, env ));
receFields.insert(pair<QString,int>( qdCmd, rec ));
descriptions.insert(pair<QString, Categories>( qdCmd, Desc) );
}
cat= cat.nextSibling();
}
model->setItem(r++,item);
}
}
n = n.nextSibling();
}
file.close();
return 0;
In between parsing I already assembly the menu. After all, I already have all set for updating the XML when the user edits the xml file and reloads at the application, I simply erase the tree and recreate it again. You can see that I also pass some data onto some structures, they are basically std::vector and std::map. This code above was written with examples from the Qt documentation, which are quite decent by the way.
It happens that I wrote a simple dialog to make the user avoiding editing the XML. Ok, for me it might be easier and simpler to edit the XML even from the user perspective, but the possible users will prefer to edit things on the dialog. This is all OK. I can grab the data pass it to the application. No trouble at all.
But I need to update the XML. Basically an edit will consist into updating the node by either adding a new one or inserting a child node into under . How do I update a node ? Is there any specific way to accomplish that ? My experiences with XML are short, I usually write, update, parse txt and binary files.
I want to do something like:
if( root.tagName() != "comandos" )
return -3;
QDomNode n = root.firstChild();
while( !n.isNull() )
{
QDomElement e = n.toElement();
if( !e.isNull() )
{
if( e.tagName() == "categoria" )
{
QDomNode cat = n.firstChild();
while( !cat.isNull() )
{
QDomElement CatName = cat.toElement();
if ( CatName.tagName() == "nome")
{
QString s = CatName.text();
if ( s != qsCategory )
{
// we have not found the category
// add it here
}
else
{
// the category exists simply update
}
}
cat= cat.nextSibling();
}
}
}
n = n.nextSibling();
}
It seems that using Qt Dom is quite decent for parsing and creating XML files, but it lacks the tools for updates. Any help would be much appreciated, even an example.
This other thread here, looks useful
Edit Value of a QDomElement?
I have looked over the internet for examples that would update a XML file. It seems that if I catch the current node I can add a child to it, so far I did not figure out how to do so.
Thanks for the help and obviously sorry for my ignorance.
QDomElement newCategoriaTag = doc.createElement(QString("categoria"));
QDomElement newNomeTag = doc.createElement(QString("nome"));
QDomText newNomeText = doc.createTextNode(QString("Cupom fiscal 2"));
newNomeTag.appendChild(newNomeText);
newCategoriaTag.appendChild(newNomeTag);
root.appendChild(newCategoriaTag);
This will result in:
<comandos>
<categoria>
<nome>Cupom fiscal</nome>
<comando>
<nome>01 - Abrir Cupom Fiscal</nome>
<env>3</env>
<rec>4</rec>
<desc>CNPJ / CPF : </desc>
<desc>Nome : </desc>
<desc>Endereco: </desc>
</comando>
</categoria>
<categoria>
<nome>Cupom fiscal 2</nome>
</categoria>
</comandos>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With