关闭

Linux下XPath对xml解析

标签: xmlxpath注释xml解析
286人阅读 评论(0) 收藏 举报
分类:
#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;
}

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:148979次
    • 积分:4057
    • 等级:
    • 排名:第7951名
    • 原创:257篇
    • 转载:5篇
    • 译文:0篇
    • 评论:30条
    博客专栏