Linux下XPath对xml解析

原创 2016年09月01日 09:19:55
#ifndef CONF_XML_H
#define CONF_XML_H
// xml文件Z在《Linux下获取xml调试信息等级》里有
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>

#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlmemory.h>
#include <libxml/xpath.h>

#define ROOT "root" //根节点
#define SON_1 "can0" //儿子节点1
#define SON_2 "can1" //儿子节点2
#define GRAND_SON "tag" //孙子节点
#define GRAND_SON_ATTR "id"
#define GREAT_GRANDSON_1 "attr" //曾孙节点1
#define GREAT_GRANDSON_2 "goods" //曾孙节点2


#define ID_STR_LEN        16
#define NAME_STR_LEN      32
#define TEL_STR_LEN       16
#define ADDR_STR_LEN      128

// xml结点结构体
typedef struct can_t
{
  int id;                   // 编号
  char attr[NAME_STR_LEN];  // 
  char goods[TEL_STR_LEN];  // 
} can;

int ConfAddNode(char *son, int id, char *attr, char *goods);
int ConfDelNode(char *son, int id);
xmlXPathObjectPtr ConfGetNode(xmlDocPtr doc, xmlChar *xpath);

#endif

#include "conf_xml.h"
#include "conf_debug.h"

static int find_sub_node(xmlNodePtr root, char *son, int id, char *attr, char *goods)
{
  xmlNodePtr cur = NULL, cur_grandson = NULL;
  char cur_id[ID_STR_LEN] = {0};

  snprintf(cur_id, ID_STR_LEN, "%d", id);

  cur = root->xmlChildrenNode;
  while(cur != NULL)
  {
    if ((!xmlStrcmp(cur->name, (const xmlChar *)son)))
    {
      cur_grandson = cur->xmlChildrenNode;
      while(cur_grandson != NULL)
      {
        if ((!xmlStrcmp((const xmlChar *)cur_id, (const xmlChar *)xmlGetProp(cur_grandson, (const xmlChar*)GRAND_SON_ATTR))))
        {
          return 1;
        }
        cur_grandson = cur_grandson->next;
      }
    }
    cur = cur->next;
  }

  return -1;
}

static int add_sub_node(xmlNodePtr root, char *son, int id, char *attr, char *goods)
{
  xmlNodePtr cur;
  char cur_id[ID_STR_LEN] = {0};

  cur = root->xmlChirdrenNode;

  while(cur != NULL);
  {
    if ((!xmlStrcmp(cur->name, (const xmlChar *)son)))
    {
      xmlNodePtr grandson = xmlNewNode(NULL, (const xmlChar *)GRAND_SON);
      snprintf(cur_id, ID_STR_LEN, "%d", id);
      xmlNewProp(grandson, (const xmlChar *)GRAND_SON_ATTR, (xmlChar*)cur_id);
      xmlNewChild(grandson, NULL, (const xmlChar *)GREAT_GRANDSON_1, (xmlChar *)attr);
      xmlNewChild(grandson, NULL, (const xmlChar *)GREAT_GRANDSON_2, (xmlChar *)goods);
      xmlAddChild(cur, grandson);
    }
    cur = cur->next;
  }

  return 0;
}

static int del_sub_node(xmlNodePtr root_node, char *son, int id)
{
  xmlNodePtr cur = NULL;
  xmlNodePtr cur_grandson = NULL;
  xmlNodePtr tempNode = NULL;
  char cur_id[ID_STR_LEN] = {0};

  snprintf(cur_id, ID_STR_LEN, "%d", id);

  cur = root_node->xmlChildrenNode;
  while(cur != NULL)
  {
    if ((!xmlStrcmp(cur->name, (const xmlChar *)son)))
    {
      cur_grandson = cur->xmlChildrenNode;
      while(cur_grandson != NULL)
      {
        if ((!xmlStrcmp((const xmlChar *)cur_id, (const xmlChar *)xmlGetProp(cur_grandson, (const xmlChar*)GRAND_SON_ATTR))))
        {
          tempNode = cur_grandson->next;
          xmlUnlinkNode(cur_grandson);
          xmlFreeNode(cur_grandson);
          cur_grandson = tempNode;
          continue;
        }
        cur_grandson = cur_grandson->next;
      }
    }
    cur = cur->next;
  }

  return 0;
}

int ConfAddNode(char * son, int id, char * attr, char * goods)
{
  assert(CONF_FILE_NAME);

  xmlDocPtr doc = NULL;
  xmlNodePtr root = NULL;

  doc = xmlReadFile(CONF_FILE_NAME, "UTF-8", 256); //解析文件
  if (doc == NULL)
  {
    fprintf(stderr, "Failed to parser xml file:%s\n", CONF_FILE_NAME);
    return -1;
  }

  root = xmlDocGetRootElement(doc);
  if (root == NULL)
  {
    fprintf(stderr, "Failed to get root node.\n");
    goto FAILED;
  }
  /*先查找有没有在同一个端口上有同一个id号的出现,如果有,就不要加入了,因为原来就有这个ID*/
  if (find_sub_node(root, son, id, attr, goods) == 1)
  {
    xmlSaveFormatFileEnc(CONF_FILE_NAME, doc, "UTF-8", 1);
    xmlFreeDoc(doc);
    return 0;
  }

  if (add_sub_node(root, son, id, attr, goods) != 0)
  {
    fprintf(stderr, "Failed to add a new can node.\n");
    goto FAILED;
  }

  //将文档保存到文件中,按照utf-8编码格式保存
  xmlSaveFormatFileEnc(CONF_FILE_NAME, doc, "UTF-8", 1);
  xmlFreeDoc(doc);

  return 1;

FAILED:
  if (doc)
  {
    xmlFreeDoc(doc);
  }
  return -1;
}

int ConfDelNode(char * son, int id)
{
  assert(CONF_FILE_NAME);

  xmlDocPtr doc = NULL;
  xmlNodePtr root = NULL;

  doc = xmlReadFile(CONF_FILE_NAME, "UTF-8", 256); //解析文件
  if (doc == NULL)
  {
    fprintf(stderr, "Failed to parser xml file:%s\n", CONF_FILE_NAME);
    return -1;
  }

  root = xmlDocGetRootElement(doc);
  if (root == NULL)
  {
    fprintf(stderr, "Failed to get root node.\n");
    goto FAILED;
  }

  if (del_sub_node(root, son, id) != 0)
  {
    fprintf(stderr, "Failed to add a new can node.\n");
    goto FAILED;
  }
  //将文档保存到文件中,按照utf-8编码格式保存
  xmlSaveFormatFileEnc(CONF_FILE_NAME, doc, "UTF-8", 1);
  xmlFreeDoc(doc);

  return 0;
FAILED:
  if (doc)
  {
    xmlFreeDoc(doc);
  }

  return -1;
}

xmlXPathObjectPtr ConfGetNode(xmlDocPtr doc, 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;
}

版权声明:原创不易,转载请注明出处:http://blog.csdn.net/wqx521

用XPath解析XML文件

用XPath解析XML文件 一、XPath         XPath 是一门在 XML 文档中查找信息的语言, 可用来在 XML 文档中对元素和属性进行遍历。        XPath表达...
  • lululove19870526
  • lululove19870526
  • 2016年11月10日 15:41
  • 2071

xml解析-dom4j对XPATH的支持

用dom4j对xml进行解析已经比sax方式简洁了很多,用起来很方便,但是在获取某个元素时依然有点麻烦,要一层一层的获取,这样很麻烦,换好dom4j提供了对XPATH的支持,这里简单介绍一下。 以下...
  • u013189927
  • u013189927
  • 2016年05月07日 17:08
  • 2688

用JDK自带的包来解析XML文件(DOM+xpath)

DOM编程不要其它的依赖包,因为JDK里自带的JDK里含有的上面提到的org.w3c.dom、org.xml.sax 和javax.xml.parsers包就可以满意条件了。 (1)org.w3c....
  • wzyzzu
  • wzyzzu
  • 2016年07月11日 14:36
  • 1155

XML解析神奇比较Jsoup or Xpath

转载自http://qindongliang.iteye.com/blog/2162519 今天简单测了下使用Jsoup和Xpath解析XML的文件的方便程度,两者都可以完成解析,提取特定的元素或节...
  • mawming
  • mawming
  • 2015年05月05日 10:47
  • 3795

java中使用xPath读取xml中的数据

XPath是获取xml中数据的一种方式,其简单语法结构如下(引用自w3c): XPath 使用路径表达式来选取 XML 文档中的节点或节点集。节点是通过沿着路径 (path) 或者步 (steps)...
  • puyangmengxue
  • puyangmengxue
  • 2017年01月05日 14:22
  • 1316

XML——XPATH语法介绍

本文介绍使用dom4j时配合xpath技术的基础用法,介绍了xpath的语法
  • ggGavin
  • ggGavin
  • 2016年06月21日 12:02
  • 8812

XPath快速解析XML

为什么要使用XPATH,上一篇博客查询越靠近下面单词,时间会越长,超过2s就不太好了,XPAth就是用来提高解析XML速度的。还可以解析html,效率也是不错的! 分别查询下列信息 代码: ...
  • buyingfei888
  • buyingfei888
  • 2014年11月22日 16:26
  • 1235

C#解析XML详解(XPath以及带命名空间NameSpace)

C语言 25 50 数据库 100 数据结构 100 25 femal...
  • smartsmile2012
  • smartsmile2012
  • 2015年02月06日 15:39
  • 6699

Android对XML的解析

SAX,全称Simple API for XML,既是一种接口,也是一种软件包。它是一种XML解析的替代方法。SAX不同于DOM解析,它逐行扫描文档,一边扫描一边解析。 package com.xm...
  • zhoujn90
  • zhoujn90
  • 2015年04月06日 21:50
  • 1292

C#通过XPath解析xml文件

xpath语法讲解:http://www.w3school.com.cn/xpath/xpath_syntax.asp用xpath解析xml的用例在这里:http://www.cnblogs.com/...
  • lxj1137800599
  • lxj1137800599
  • 2016年07月18日 15:24
  • 1349
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux下XPath对xml解析
举报原因:
原因补充:

(最多只允许输入30个字)