TinyXML(TinyXPath) 使用总结

原来的Windows 平台下的项目使用了MSXML组件来访问Web Service 接口,后来因为跨平台的需要,在Linux平台下改用了GSOAP+TinyXML(TinyXPath)来完成所需功能。使用TinyXPath还是遇到了一些问题,总结一下。

这里要说明一下TinyXPath是TinyXML+XPath,下载TinyXPath包的时候会包含TinyXML的原文件。

1. 使用XPath,来获取XML子节点

TinyXpath所支持的XPath并不完整,而且缺少文档资料,试了一整天才试出来,直接把结果写下来

1.)节点名大小写无关匹配

这里要用到name函数和translate函数,首先转化所有的节点名到大写,然后再比较。语法如下:

*[translate(name(), 'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')='XXXX']

name函数返回节点名字,translate函数转换到大写。

2.)节点内容比较

text函数返回节点内容, 语法为

*[text()='XXXX']

3.)选择固定位置节点

position函数用以指定第几个节点,语法为:

*[position()=XXX] ,此处是数字类型

举个例子,我们要选定节点名字为AAA,内容为BBB的第二个节点,XPath应改名为:

*[translate(name(), 'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')='AAA' and text()='BBB' and  position()=2]

这里还有个查询效率问题,并不确定把 position()=2 条件放在最前面是不是可以提高效率。以上内容可以封装成一个函数:

inline string getNodeXPath(const string & strNodeName, string strText="", string pos="")
{
    string strVal;
    strVal += "*[";
    strVal += "translate(name(), 'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ') = '"+ strNode Name + "'";
    if(!strText.empty())
        strVal +=" and text()= '" +strText+"'";

    if(!pos.empty())
        strVal +=" and position()= " +pos;

    strVal += "]";

    return strVal;
}

#define NODE(node) getNode(node)
#define NODE_AT(node,pos)  getNode(node,"",pos)

4.) 查询子节点满足一定条件的节点

没有看到TinyXPath提供的直接可以获取子节点内容的函数,这里使用变通的方法,即先判断子节点条件然后使用parent关键词指定返回父节点 , 定义了HAS_CHILD宏

#define HAS_CHILD(node,txt) string(string("/")+getNode(node,txt)+string("/parent::*"))

举个例子:

string strXPath;

strXPath=  "/" + NODE("XMLDATA") + "/" + NODE("RATES") ;
strXPath+= "/" + NODE("REPORATEVO") +HAS_CHILD("TERMBYYEAR",mStrType)+HAS_CHILD("CONTRACTDATE",mStrSubType);
strXPath+= "/" + NODE("RATE");

多个HAS_CHILD之间是并列关系。

以下是获取节点的代码段:

       TiXmlDocument xdoc;
        xdoc.Parse(wsResponse.c_str());
        if(xdoc.Error())
        {
            return 3;
        }

        const TiXmlElement *  xmain=xdoc.RootElement();
        TinyXPath::xpath_processor  xproc(xmain,xpath.c_str());

        unsigned  nodeCount =xproc.u_compute_xpath_node_set();
        if(nodeCount==0)
        {
            return 4;
        }

        TiXmlNode * xnode = xproc.XNp_get_xpath_node(0);

2. 子节点内容读取

TiXmlPrinter 提供了获取节点内容到内存的方法,

代码如下:

TiXmlPrinter printer;
xchild->Accept(&printer);
strRes = printer.CStr();

这里有个问题,打印时候'/n'回车符,保存的字符串里会是空格,'/r/n' 才是回车换行。

总结到这里,希望对使用TinyXPath的人有帮助。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
tinyxpath 解析简单 的小工具,输出是一个静态库。可 找到xml文档. TinyXml介绍 TinyXml是一个基于DOM模型的、非验证的轻量级C++解释器 一. XML解析模型: 目前XML的解析主要有两大模型:SAX和DOM。 SAX是基于事件的,其基本工作流程是分析XML文档,当发现了一个新的元素时,产生一个对应事件,并调用相应的用户处理函数。这种方式占用内存少,速度快,但用户程序相应得会比较复杂。 DOM(文档对象模型),则是在分析时,一次性的将整个XML文档进行分析,并在内存中形成对应的树结构,同时,向用户提供一系列的接口来访问和编辑该树结构。这种方式占用内存大,速度往往慢于SAX,但可以给用户提供一个面向对象的访问接口,对用户更为友好。 另据说,一些同时提供了SAX和DOM接口的库,是在底层先实现SAX,再在SAX的基础上实现DOM 对于一个特定的XML文档而言,其正确性分为两个层次。 首先是其格式应该符合XML的基本格式要求,比如第一行要有声明,标签的嵌套层次必须前后一致等等,符合这些要求的文件,就是一个合格的XML文件,称作well-formatted。 其次,一个XML文档因其内容的不同还必须在语义上符合相应的标准,这些标准由相应的DTD文件或者Schema文件来定义,符合了这些定义要求的XML文件,称作valid。 因此,解析器也分为两种,一种是验证的,即会跟据XML文件中的声明,用相应的DTD文件对XML文件进行校验,检查它是否满足DTD文件的要求。另一种是忽略DTD文件,只要基本格式正确,就可以进行解析。 就我所知,验证的解析器通常都是比较重量级的。TinyXml不支持验证,但是体积很小,用在解析格式较为简单的XML文件,比如配置文件时,特别的合适。
TinyXML是一个小型的、简单易用的XML解析器,适用于C++环境。它的主要特点是简单易用、轻量级、跨平台、可移植性强。本文将介绍TinyXML使用方法。 ## TinyXML的安装 TinyXML的安装非常简单,只需要下载TinyXML的源代码,并将其包含到你的项目中即可。TinyXML的源代码可以在其官方网站(http://www.grinninglizard.com/tinyxml/)上下载。 ## TinyXML的基本用法 TinyXML使用非常简单,只需要包含TinyXML头文件,并使用其提供的API即可完成XML文件的解析和生成。 ### 解析XML文件 以下是一个简单的XML文件example.xml: ``` <?xml version="1.0" encoding="UTF-8"?> <root> <person> <name>John</name> <age>20</age> </person> <person> <name>Jane</name> <age>21</age> </person> </root> ``` 我们可以使用如下代码来解析该XML文件: ```c++ #include "tinyxml.h" #include <iostream> using namespace std; int main() { TiXmlDocument doc("example.xml"); bool loadOkay = doc.LoadFile(); if (loadOkay) { TiXmlNode* root = doc.FirstChild("root"); if (root) { for (TiXmlNode* node = root->FirstChild(); node; node = node->NextSibling()) { if (node->Type() == TiXmlNode::TINYXML_ELEMENT && strcmp(node->Value(), "person") == 0) { TiXmlNode* nameNode = node->FirstChild("name"); TiXmlNode* ageNode = node->FirstChild("age"); if (nameNode && ageNode) { cout << "name:" << nameNode->FirstChild()->Value() << endl; cout << "age:" << ageNode->FirstChild()->Value() << endl; } } } } } return 0; } ``` 上述代码首先创建了一个TiXmlDocument对象,并调用其LoadFile方法加载example.xml文件。如果加载成功,则获取XML文档的根节点,并循环遍历根节点的所有子节点,查找名称为“person”的节点,并获取其下的“name”和“age”子节点的值。 ### 生成XML文件 我们可以使用TinyXML来生成XML文件。以下是一个简单的示例: ```c++ #include "tinyxml.h" #include <iostream> using namespace std; int main() { TiXmlDocument doc; TiXmlElement* root = new TiXmlElement("root"); doc.LinkEndChild(root); for (int i = 0; i < 3; i++) { TiXmlElement* person = new TiXmlElement("person"); root->LinkEndChild(person); TiXmlElement* name = new TiXmlElement("name"); person->LinkEndChild(name); TiXmlText* nameText = new TiXmlText("John"); name->LinkEndChild(nameText); TiXmlElement* age = new TiXmlElement("age"); person->LinkEndChild(age); TiXmlText* ageText = new TiXmlText("20"); age->LinkEndChild(ageText); } doc.SaveFile("example.xml"); return 0; } ``` 上述代码创建了一个TiXmlDocument对象,并创建了一个名为“root”的根节点。然后循环生成三个名为“person”的节点,并为每个节点添加名为“name”和“age”的子节点,并设置其值。最后,调用TiXmlDocument的SaveFile方法将生成的XML文件保存到example.xml中。 ## 小结 TinyXML是一个简单易用的XML解析器,适用于C++环境,其主要特点是简单易用、轻量级、跨平台、可移植性强。使用TinyXML可以轻松地解析和生成XML文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值