最近做项目总是有解析xml的需求,而迅速定位到所需节点然后进行读取、修改、删除操作是常有的事情,为此,我学习了xpath的用法,总结如下:
首先,libxml2的官方文档被墙了,只能百度。找到一篇文章:https://www.cnblogs.com/catgatp/p/6505427.html
文章里介绍的方法很实用,我拿过来修改后自己测试并调整。
示例代码如下,参照着使用就行了。
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
/**
* @brief xpathxml
*
* @param doc xmlָ
* @param xpath ath
* @return xmlXPathObjectPtr LLָlXPathFreeObject
*/
static xmlXPathObjectPtr xml_get_nodeset(xmlDocPtr doc, const xmlChar *xpath)
{
xmlXPathContextPtr context;
xmlXPathObjectPtr result;
context = xmlXPathNewContext(doc);
if (context == NULL)
{
printf("context is NULL\n");
return NULL;
}
result = xmlXPathEvalExpression(xpath, context);
xmlXPathFreeContext(context);
if (result == NULL)
{
printf("xmlXPathEvalExpression return NULL\n");
return NULL;
}
if (xmlXPathNodeSetIsEmpty(result->nodesetval))
{
xmlXPathFreeObject(result);
printf("nodeset is empty\n");
return NULL;
}
return result;
}
int main(int argc, char const *argv[])
{
xmlDocPtr doc = xmlReadFile("./test.xml", "utf-8", XML_PARSE_NOBLANKS);
if (NULL == doc)
{
return -1;
}
xmlChar *xpath = BAD_CAST "//name";
xmlXPathObjectPtr result = xml_get_nodeset(doc, xpath);
if (NULL == result)
{
xmlFreeDoc(doc);
return -1;
}
xmlNodeSetPtr nodeset = result->nodesetval;
xmlNodePtr cur = NULL;
for (int i = 0; i < nodeset->nodeNr; i++)
{
cur = nodeset->nodeTab[i];
xmlChar *name = xmlNodeGetContent(cur);
printf("find:%d %s\n", i, name);
xmlFree(name);
}
xmlXPathFreeObject(result);
xmlFreeDoc(doc);
return 0;
}
值得一提的是xpath有自己的语法,可百度。可参考:https://www.w3school.com.cn/xpath/xpath_syntax.asp