libxml的使用(4)--xpath搜索节点树

在libxml的tutorial中介绍了一种用关键字查找节点的方法,这种方法将使用打xpath系列API。由于我才刚刚接触libxml,所以我对xpath的认识也仅仅是在tutorial提供的功能之内了。废话少说,直接进入整体。

我们在操作xml文件是经常需要根据特定的条件查找一系列的节点,为了实现这样的功能,我们需要一个xmlXPathContextPtr和一个expression。我们调用xmlXPathEvalExpression函数来得到一个xmlXPathObjectPtr指针,这个指针包含了一个xmlNodeSetPtr,其中有一个变量nodeTab是我们所需要的节点数组。

xmlXPathObjectPtr ret = NULL;
xmlXPathContextPtr con = NULL;

con = xmlXPathNewContext(doc);
ret = xmlXPathEvalExpression((xmlChar*)expr, con);
xmlXPathFreeContext(con);

这样我们就得到了查询的结果了。expr是查询的条件,tutorial给的例子里,这个条件是“//keyword”,表示找出所有名称为keyword的节点。至于其他的条件,我现在还不知道。

得到了查询的结果,我们就要对结果进行处理。

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>
	<head>
		<title>web</title>
	</head>
	<body>
		<a href="www.baidu.com">baidu</a>
		<a href="www.google.com">Google</a>
	</body>
</html>

link.c

#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;
}

输出结果为:

link address:www.baidu.com
link address:www.google.com


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值