我有一个基于树 Qt 组件构建左侧菜单的应用程序。为了加载它,我需要解析一个 XML 文件。 XML 文件如下所示:
<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>
我实际上可以使用 QtDOM 读取此 XML。
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;
在解析之间我已经组装了菜单。毕竟,当用户编辑 xml 文件并在应用程序中重新加载时,我已经完成了更新 XML 的所有设置,我只需删除树并重新创建它。你可以看到我也将一些数据传递给了一些结构,它们基本上是 std::vector 和 std::map。上面的代码是使用 Qt 文档中的示例编写的,顺便说一句,这些示例相当不错。
碰巧我写了一个简单的对话框让用户避免编辑 XML。好的,对我来说,即使从用户的角度来看,编辑 XML 也可能更容易、更简单,但可能的用户会更喜欢在对话框中编辑内容。这一切都可以。我可以抓取数据并将其传递给应用程序。一点问题都没有。
但我需要更新 XML。基本上,编辑将包括通过添加新节点或将子节点插入 under 来更新节点。如何更新节点?有没有什么具体的方法可以做到这一点?我在 XML 方面的经验很短,我通常编写、更新、解析 txt 和二进制文件。
我想做这样的事情:
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();
}
似乎使用 Qt Dom 来解析和创建 XML 文件相当不错,但它缺少更新工具。任何帮助将不胜感激,即使是一个例子。
这里的另一个线程,看起来很有用
我在 Internet 上查找了更新 XML 文件的示例。似乎如果我捕获当前节点,我可以向它添加一个子节点,到目前为止我还没有弄清楚该怎么做。
感谢您的帮助,显然对我的无知感到抱歉。
最佳答案
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);
这将导致:
<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>
关于xml - 使用 Qt DOM 更新 XML 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9804686/