libxml的使用(4)--xpath搜索节点树
2014-03-19 16:57
246 查看
http://blog.csdn.net/hdutigerkin/article/details/7546912
在libxml的tutorial中介绍了一种用关键字查找节点的方法,这种方法将使用打xpath系列API。由于我才刚刚接触libxml,所以我对xpath的认识也仅仅是在tutorial提供的功能之内了。废话少说,直接进入整体。
我们在操作xml文件是经常需要根据特定的条件查找一系列的节点,为了实现这样的功能,我们需要一个xmlXPathContextPtr和一个expression。我们调用xmlXPathEvalExpression函数来得到一个xmlXPathObjectPtr指针,这个指针包含了一个xmlNodeSetPtr,其中有一个变量nodeTab是我们所需要的节点数组。
[cpp] view
plaincopyprint?
xmlXPathObjectPtr ret = NULL;
xmlXPathContextPtr con = NULL;
con = xmlXPathNewContext(doc);
ret = xmlXPathEvalExpression((xmlChar*)expr, con);
xmlXPathFreeContext(con);
这样我们就得到了查询的结果了。expr是查询的条件,tutorial给的例子里,这个条件是“//keyword”,表示找出所有名称为keyword的节点。至于其他的条件,我现在还不知道。
得到了查询的结果,我们就要对结果进行处理。
[cpp] view
plaincopyprint?
if(NULL == ret) {
fprintf(stderr, "eval func error\n");
exit(1);
}
if(xmlXPathNodeSetIsEmpty(ret->nodesetval)){
fprintf(stderr, "node set empty\n");
xmlXPathFreeObject(ret);
exit(1);
}
xmlNodeSetPtr nodeset = ret->nodesetval;
int i;
for(i = 0; i < nodeset->nodeNr; i ++) {
//handle the node
}
xmlXPathFreeObject(ret);
下面是一个程序的实例。用于提取出网页中的链接:
web.html
[html] view
plaincopyprint?
<html>
<head>
<title>web</title>
</head>
<body>
<a href="www.baidu.com">baidu</a>
<a href="www.google.com">Google</a>
</body>
</html>
link.c
[cpp] view
plaincopyprint?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>
static xmlDocPtr
getDocPtr(char* docname) {
xmlDocPtr doc = NULL;
xmlKeepBlanksDefault(0);
doc = xmlParseFile(docname);
if(NULL == doc) {
fprintf(stderr, "document cannot be parsed!\n");
exit(1);
}
return doc;
}
static xmlXPathObjectPtr
getXPathObjectPtr(xmlDocPtr doc, xmlChar* xpath_exp) {
xmlXPathObjectPtr result;
xmlXPathContextPtr context;
context = xmlXPathNewContext(doc);
result = xmlXPathEvalExpression((const xmlChar*)xpath_exp, context);
xmlXPathFreeContext(context);
if(NULL == result) {
fprintf(stderr, "eval expression error!\n");
return NULL;
}
if(xmlXPathNodeSetIsEmpty(result->nodesetval)) {
fprintf(stderr, "empty node set!\n");
xmlXPathFreeObject(result);
return NULL;
}
return result;
}
int main() {
char* docname = "web.html";
xmlDocPtr doc = NULL;
xmlXPathObjectPtr xpath_obj = NULL;
xmlNodeSetPtr nodeset = NULL;
xmlChar* xpath_exp = (xmlChar*)"//a";
xmlChar* uri;
doc = getDocPtr(docname);
xpath_obj = getXPathObjectPtr(doc, xpath_exp);
if(NULL != xpath_obj) {
nodeset = xpath_obj->nodesetval;
int i = 0;
for(i = 0; i < nodeset->nodeNr; i ++) {
uri = xmlGetProp(nodeset->nodeTab[i],(const xmlChar*)"href");
printf("link address:%s\n",uri);
xmlFree(uri);
}
xmlXPathFreeObject(xpath_obj);
}
xmlFreeDoc(doc);
xmlCleanupParser();
return 1;
}
输出结果为:
[html] view
plaincopyprint?
link address:www.baidu.com
link address:www.google.com
在libxml的tutorial中介绍了一种用关键字查找节点的方法,这种方法将使用打xpath系列API。由于我才刚刚接触libxml,所以我对xpath的认识也仅仅是在tutorial提供的功能之内了。废话少说,直接进入整体。
我们在操作xml文件是经常需要根据特定的条件查找一系列的节点,为了实现这样的功能,我们需要一个xmlXPathContextPtr和一个expression。我们调用xmlXPathEvalExpression函数来得到一个xmlXPathObjectPtr指针,这个指针包含了一个xmlNodeSetPtr,其中有一个变量nodeTab是我们所需要的节点数组。
[cpp] view
plaincopyprint?
xmlXPathObjectPtr ret = NULL;
xmlXPathContextPtr con = NULL;
con = xmlXPathNewContext(doc);
ret = xmlXPathEvalExpression((xmlChar*)expr, con);
xmlXPathFreeContext(con);
这样我们就得到了查询的结果了。expr是查询的条件,tutorial给的例子里,这个条件是“//keyword”,表示找出所有名称为keyword的节点。至于其他的条件,我现在还不知道。
得到了查询的结果,我们就要对结果进行处理。
[cpp] view
plaincopyprint?
if(NULL == ret) {
fprintf(stderr, "eval func error\n");
exit(1);
}
if(xmlXPathNodeSetIsEmpty(ret->nodesetval)){
fprintf(stderr, "node set empty\n");
xmlXPathFreeObject(ret);
exit(1);
}
xmlNodeSetPtr nodeset = ret->nodesetval;
int i;
for(i = 0; i < nodeset->nodeNr; i ++) {
//handle the node
}
xmlXPathFreeObject(ret);
下面是一个程序的实例。用于提取出网页中的链接:
web.html
[html] view
plaincopyprint?
<html>
<head>
<title>web</title>
</head>
<body>
<a href="www.baidu.com">baidu</a>
<a href="www.google.com">Google</a>
</body>
</html>
link.c
[cpp] view
plaincopyprint?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>
static xmlDocPtr
getDocPtr(char* docname) {
xmlDocPtr doc = NULL;
xmlKeepBlanksDefault(0);
doc = xmlParseFile(docname);
if(NULL == doc) {
fprintf(stderr, "document cannot be parsed!\n");
exit(1);
}
return doc;
}
static xmlXPathObjectPtr
getXPathObjectPtr(xmlDocPtr doc, xmlChar* xpath_exp) {
xmlXPathObjectPtr result;
xmlXPathContextPtr context;
context = xmlXPathNewContext(doc);
result = xmlXPathEvalExpression((const xmlChar*)xpath_exp, context);
xmlXPathFreeContext(context);
if(NULL == result) {
fprintf(stderr, "eval expression error!\n");
return NULL;
}
if(xmlXPathNodeSetIsEmpty(result->nodesetval)) {
fprintf(stderr, "empty node set!\n");
xmlXPathFreeObject(result);
return NULL;
}
return result;
}
int main() {
char* docname = "web.html";
xmlDocPtr doc = NULL;
xmlXPathObjectPtr xpath_obj = NULL;
xmlNodeSetPtr nodeset = NULL;
xmlChar* xpath_exp = (xmlChar*)"//a";
xmlChar* uri;
doc = getDocPtr(docname);
xpath_obj = getXPathObjectPtr(doc, xpath_exp);
if(NULL != xpath_obj) {
nodeset = xpath_obj->nodesetval;
int i = 0;
for(i = 0; i < nodeset->nodeNr; i ++) {
uri = xmlGetProp(nodeset->nodeTab[i],(const xmlChar*)"href");
printf("link address:%s\n",uri);
xmlFree(uri);
}
xmlXPathFreeObject(xpath_obj);
}
xmlFreeDoc(doc);
xmlCleanupParser();
return 1;
}
输出结果为:
[html] view
plaincopyprint?
link address:www.baidu.com
link address:www.google.com
相关文章推荐
- libxml的使用(4)--xpath搜索节点树
- libxml的使用(4)--xpath搜索节点树 http://blog.csdn.net/hdutigerkin/article/details/7546912
- libxml的使用(4)--xpath搜索节点树
- 在Dom4j中使用Xpath搜索xml的元素节点
- 在Dom4j中使用Xpath搜索xml的元素节点
- libxml的使用(2)--读取节点属性
- 使用xpath取得节点的text
- libxml的使用(3)--编辑节点
- 使用XPATH查找xml文档节点
- Dom4j使用Xpath语法读取xml节点
- XPath 使用路径表达式来选取 XML 文档中的节点或节点集
- 完全二叉树统计节点个数【使用二分搜索】
- Xpath使用text()函数取得节点值
- C#使用xpath找到一个节点
- Dom4j使用Xpath语法读取xml节点
- 在Delphi的XmlDom中使用XPath选中单个IXMLNode / TXmlNode 节点
- 使用 XPath 导航选择节点
- 用XPath精确定位节点元素&selenium使用Xpath定位之完整篇
- Dom4j使用Xpath语法读取xml节点
- 使用xPath技术快速获取指定节点并对其修改--(xPath技术基础)