XPath在QT中的使用(QXmlQuery读取XML文件)
2011-08-03 17:50
369 查看
最近一段时间和Xml文件算是干上了,先后用了QXmlStream、Dom、Dhtmlxtree、DhtmlXform方式读写Xml文件。昨天接到任务让用Xpath方式实现Xml读取。经过了解在QT中有QxmlQuery类用来实现XPath,接下来就说说这个东东!
1.lib文件:
要想用QXmlQuery,首先要包含进两个lib文件:QtXmlPatterns4.lib 和 QtXmlPatternsd4.lib
2.头文件:
用的一下这个头文件
3.xml格式:
请仔细看我的xml格式,你会发现每一个二级目录下会出现UserDate属性,而内容竟然是个标准的xml文件的语句,之所以这样是项目的需要,这个格式有个好处,如果你对Dhtmlx库了解的话,你会发现:外层的xml格式是DhtmlXTree的标准格式,而内层的xml格式为DhtmlxForm标准格式。明白了吧,实在不明白,上个图吧:
看懂了吧,左侧是个tree,右侧自动生成form,而且还实现了,对form的写入,具体代码在其他文章中提及了。好了,扯远了。
4.关于QXmlQuery的使用
:
写到这里很多朋友可能会问,既然用Dom方式就能读取Xml,干嘛还用这种方式呢,其实仔细看看我的xml格式,你会发现用QXmlQuery读我的外层xml格式会十分方便,这就是为什么用这个了。
4.目标
最后说一下,我们这个任务
我的xml格式如上,当输入(xml目录、一级目录、二级目录、三级目录、返回出错信息),会返回相应的value值。
整个代码如下:
调用方式是:
当然,我这是截取了一部分代码,因为我写的QT插件,所以调用代码实在另一个工程里。
好了,就这些吧。
5.资料:
QXmlQuery在线帮助文档
QT菜鸟一只,欢迎批评指正!
1.lib文件:
要想用QXmlQuery,首先要包含进两个lib文件:QtXmlPatterns4.lib 和 QtXmlPatternsd4.lib
2.头文件:
用的一下这个头文件
#include <QtXmlPatterns/QXmlQuery>
3.xml格式:
<?xml version="1.0"?> <tree id="0"> <item id="1" open="1" text="工作目录" im0="leaf.gif" im1="folderOpen.gif" im2="folderClosed.gif" > <item id="11" select="1" text="工作目录" im0="leaf.gif" im1="folderOpen.gif" im2="folderClosed.gif" > <userdata name="value"> <![CDATA[ <?xml version="1.0"?> <items> <item type="label" name="label1" label="基本配置"/> <item type="checkbox" name="check3" checked="true" label="全路径" position="label-right" /> <item type="radio" name="ffff" checked="" value="online" label="单目录" position="label-right" /> <item type="radio" name="ffff" checked="true" value="disk" label="双目录" position="label-right" /> <item type="checkbox" name="check1" checked="true" label="前目录" position="label-right" /> <item type="checkbox" name="check2" checked="true" label="后目录" position="label-right" /> <item type="select" name="myselect" label="传递方式" > <option text="post" value="op111" selected="" /> <option text="get" value="op222" selected="true" /> </item> <item type="input" name="inputx" value="2007.7.27更新" label="配置描述" rows="2" position="label-left" /> </items>]]> </userdata> </item> </item> <item id="2" open="1" text="数据服务器地址" im0="leaf.gif" im1="folderOpen.gif" im2="folderClosed.gif" > <item id="21" text="地址" im0="leaf.gif" im1="folderOpen.gif" im2="folderClosed.gif" > <userdata name="value"> <![CDATA[<?xml version="1.0"?> <items> <item type="label" name="label1" label="基本配置"/> <item type="checkbox" name="check3" checked="true" label="全路径" position="label-right" /> <item type="radio" name="ffff" checked="" value="online" label="单目录" position="label-right" /> <item type="radio" name="ffff" checked="true" value="disk" label="双目录" position="label-right" /> </items>]]> </userdata> </item> </tree>
请仔细看我的xml格式,你会发现每一个二级目录下会出现UserDate属性,而内容竟然是个标准的xml文件的语句,之所以这样是项目的需要,这个格式有个好处,如果你对Dhtmlx库了解的话,你会发现:外层的xml格式是DhtmlXTree的标准格式,而内层的xml格式为DhtmlxForm标准格式。明白了吧,实在不明白,上个图吧:
看懂了吧,左侧是个tree,右侧自动生成form,而且还实现了,对form的写入,具体代码在其他文章中提及了。好了,扯远了。
4.关于QXmlQuery的使用
QXmlQuery query; QString sOptionSettings; QDomDocument configxmldoc; QFile db(sXmlPath); if ( ! db.exists()) { errMsg = "Xml文件未找到!"; return errMsg; } if (!db.open(QIODevice::ReadOnly | QIODevice::Text)){ errMsg = "文件打不开!"; return errMsg; } query.setFocus(&db); //去和我的xml格式对应一下,很容易就能看出来了。这句就是XPath的标准语法。 //sFistLabel,sSeconLabel都是参数,都=“工作目录” query.setQuery("tree[@id='0']/item[@text='"+sFistLabel+"']/item[@text='"+sSeconLabel+"']/userdata[@name='value']"); //算是检验查询参数有误 if ( !query.isValid()){ errMsg = "查询参数有误!"; return errMsg; } //把查询出来的语句,赋值给字符串sOptionSettings query.evaluateTo(&sOptionSettings); db.close(); //以下三句与我的xml格式有关,要特别注意第一句,这里默认给转行了格式。其实正确的是(见下图) sOptionSettings = sOptionSettings.replace("<","<").replace(">",">").replace("&","&"); sOptionSettings = sOptionSettings.replace("<userdata name=\"value\">",""); sOptionSettings = sOptionSettings.replace("</userdata>",""); //此时sOptionSettings是一个完整的xml语句, //而且configxmldoc为一个QDomDocument,接下来的事就是Dom解析xml格式 configxmldoc.setContent(sOptionSettings);
:
写到这里很多朋友可能会问,既然用Dom方式就能读取Xml,干嘛还用这种方式呢,其实仔细看看我的xml格式,你会发现用QXmlQuery读我的外层xml格式会十分方便,这就是为什么用这个了。
4.目标
最后说一下,我们这个任务
我的xml格式如上,当输入(xml目录、一级目录、二级目录、三级目录、返回出错信息),会返回相应的value值。
整个代码如下:
QString PSM_OptionManager::get_config_info(const QString& sXmlPath, const QString& sFistLabel, const QString& sSeconLabel, const QString& sThridLabel, QString& errMsg){ QXmlQuery query; QString sOptionSettings; QDomDocument configxmldoc; QDomNodeList sitemNodes; QFile db(sXmlPath); if ( ! db.exists()) { errMsg = "Xml文件未找到!"; return errMsg; } if (!db.open(QIODevice::ReadOnly | QIODevice::Text)){ errMsg = "文件打不开!"; return errMsg; } query.setFocus(&db); query.setQuery("tree[@id='0']/item[@text='"+sFistLabel+"']/item[@text='"+sSeconLabel+"']/userdata[@name='value']"); if ( !query.isValid()){ errMsg = "查询参数有误!"; return errMsg; } query.evaluateTo(&sOptionSettings); db.close(); sOptionSettings = sOptionSettings.replace("<","<").replace(">",">").replace("&","&"); sOptionSettings = sOptionSettings.replace("<userdata name=\"value\">",""); sOptionSettings = sOptionSettings.replace("</userdata>",""); //此时sOptionSettings是一个完整的xml语句 configxmldoc.setContent(sOptionSettings); sitemNodes = configxmldoc.elementsByTagName("item"); for (int i = 0; i < sitemNodes.count(); i++) { QDomNode node = sitemNodes.at(i); QString itemlabel = node.toElement().attribute("label"); if (itemlabel == sThridLabel ){ QString itemtype = node.toElement().attribute("type"); if(itemtype == "checkbox" || itemtype == "radio") { QString itemchecked = node.toElement().attribute("checked"); if (itemchecked == "true"){ return "1"; } else{ return "0"; } }//end if if (itemtype == "input") { QString itemvalue = node.toElement().attribute("value"); return itemvalue; }//end if if (itemtype == "select"){ QDomNodeList optionlist = node.toElement().childNodes(); for (int j = 0 ; j < optionlist.count() ; j++) { QDomNode optionnode = optionlist.at(j); QString optionchecked = optionnode.toElement().attribute("selected"); if (optionchecked == "true"){ QString optionvalue = optionnode.toElement().attribute("value"); return optionvalue; } }//end for }//end if }//end if }//end for return ""; }
调用方式是:
QString sfist = "工作目录"; QString ssecond = "工作目录"; QString sthird = "全路径"; QString sXmlPath = "E:\\settings.xml"; QString strErrMsg = ""; get_config_info(sXmlPath,sfist,ssecond,sthird, strErrMsg);
当然,我这是截取了一部分代码,因为我写的QT插件,所以调用代码实在另一个工程里。
好了,就这些吧。
5.资料:
QXmlQuery在线帮助文档
QT菜鸟一只,欢迎批评指正!
相关文章推荐
- 使用Qt中的QXmlStreamReader读取XML文件
- 使用Qt中的QXmlStreamReader读取XML文件
- 使用Qt中的QXmlStreamReader读取XML文件
- 使用XPath读取XML文件以及使用Transformer改变XML节点值
- Silverlig1.Silverlight读取外部XML加载配置-(使用WebClient读取XAP包同目录下的XML文件)
- android_xml解析之 使用SAX读取XML文件
- Java解析XML(一) 使用DOM读取XML文件
- Dom4j使用Xpath语法读取xml节点
- qt 开发过程中使用DOM方式读取XML文件
- 使用XmlReader和XmlDocument 读取xml文件,使用总结
- 转载 Silverlight实用窍门系列:1.Silverlight读取外部XML加载配置---(使用WebClient读取XAP包同目录下的XML文件))
- java中使用xPath读取xml中的数据
- 使用XmlReader和XmlDocument 读取xml文件,使用总结
- 毕业论文中使用的XML读取和制造工具!!!C++ 使用TinyXML解析XML文件
- 使用Xpath读取xml文件
- 使用Pull解析器生成XML文件和读取xml文件
- Qt5之使用流来读取xml
- LINQ学习笔记(11) LINQ to XML---不必使用.NET专门的XML类就可读取XML文件
- Silverlight实用窍门系列:1.Silverlight读取外部XML加载配置---(使用WebClient读取XAP包同目录下的XML文件))【附带实例源码】
- Dom4j使用Xpath语法读取xml节点