我有一个应用程序,它构建一个基于树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,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.基本上,编辑将包括通过添加新节点或在子节点下插入子节点来更新节点.如何更新节点?有没有具体的方法来实现这一目标?我对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文件,但它缺少更新工具.任何帮助都会非常感激,甚至是一个例子.
这里的另一个帖子看起来很有用
我查看了互联网上有关更新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>