xml.c.svn-base
上传用户:szjkjd
上传日期:2022-06-27
资源大小:8968k
文件大小:11k
源码类别:

浏览器

开发平台:

Visual C++

  1. #include <stdlib.h>
  2. #include <stdarg.h>
  3. #include <memory.h>
  4. #include <errno.h>
  5. #include <string.h>
  6. #include <libxml/xmlsave.h>
  7. #include "xml.h"
  8. TXML *xml_create(const char *filename, const char *encoding, const char *root)
  9. {
  10.         TXML *xml;
  11.         int saveno;
  12.         xmlNodePtr root_node;
  13.         if (!(xml = (TXML *)malloc(sizeof(TXML))))
  14.         {
  15.                 return NULL;
  16.         }
  17.         memset(xml, 0, sizeof(TXML));
  18.         xmlKeepBlanksDefault(0);
  19.         if (!(xml->doc = xmlNewDoc(BAD_CAST("1.0"))))
  20.         {
  21.                 saveno = errno;
  22.                 free(xml);
  23.                 errno = saveno;
  24.                 return NULL;
  25.         }
  26.         xml->encoding = strdup(encoding);
  27.         xml->filename = filename ? strdup(filename) : NULL;
  28.         root_node = xmlNewNode(NULL, BAD_CAST(root));
  29.         xmlDocSetRootElement(xml->doc, root_node);
  30.         FIFO_INIT(&xml->rubbish);
  31.         return xml;
  32. }
  33. TXML *xml_create_file(const char *filename)
  34. {
  35.         TXML *xml;
  36.         int saveno;
  37.         if (!filename)
  38.         {
  39.                 errno = EINVAL;
  40.                 return NULL;
  41.         }
  42.         if (!(xml = (TXML *)malloc(sizeof(TXML))))
  43.         {
  44.                 return NULL;
  45.         }
  46.         memset(xml, 0, sizeof(TXML));
  47.         xmlKeepBlanksDefault(0);
  48.         if (!(xml->doc = xmlParseFile(filename)))
  49.         {
  50.                 saveno = errno;
  51.                 free(xml);
  52.                 errno = saveno;
  53.                 return NULL;
  54.         }
  55.         xml->filename = strdup(filename);
  56.         FIFO_INIT(&xml->rubbish);
  57.         return xml;
  58. }
  59. TXML *xml_create_memory(const char *buffer, size_t size)
  60. {
  61.         TXML *xml;
  62.         int saveno;
  63.         if (!(buffer && size))
  64.         {
  65.                 errno = EINVAL;
  66.                 return NULL;
  67.         }
  68.         if (!(xml = (TXML *)malloc(sizeof(TXML))))
  69.         {
  70.                 return NULL;
  71.         }
  72.         memset(xml, 0, sizeof(TXML));
  73.         xmlKeepBlanksDefault(0);
  74.         if (!(xml->doc = xmlParseMemory(buffer, size)))
  75.         {
  76.                 saveno = errno;
  77.                 free(xml);
  78.                 errno = saveno;
  79.                 return NULL;
  80.         }
  81.         FIFO_INIT(&xml->rubbish);
  82.         return xml;
  83. }
  84. void xml_cleanup(TXML *xml)
  85. {
  86.         TXMLStr *res;
  87. #ifndef WIN32
  88.         while (FIFO_POP(&xml->rubbish, res, node))
  89.         {
  90.                 if (res->str)
  91.                 {
  92.                         xmlFree((xmlChar *)res->str);
  93.                 }
  94.                 free(res);
  95.         }
  96. #else
  97. FIFO_POP(&xml->rubbish, res, node);
  98. while (res)
  99. {
  100.                 if (res->str)
  101.                 {
  102.                         xmlFree((xmlChar *)res->str);
  103.                 }
  104.                 free(res);
  105. FIFO_POP(&xml->rubbish, res, node);
  106. }
  107. #endif
  108.         return;
  109. }
  110. void xml_close(TXML *xml)
  111. {
  112.         if (xml)
  113.         {
  114.                 xml_cleanup(xml);
  115.                 if (xml->object)
  116.                 {
  117.                         xmlXPathFreeObject(xml->object);
  118.                 }
  119.                 if (xml->doc)
  120.                 {
  121.                         xmlFreeDoc(xml->doc);
  122.                         xmlCleanupParser();
  123.                 }
  124.                 if (xml->encoding)
  125.                 {
  126.                         free(xml->encoding);
  127.                 }
  128.                 if (xml->filename)
  129.                 {
  130.                         free(xml->filename);
  131.                 }
  132.                 free(xml);
  133.         }
  134.         return;
  135. }
  136. int xml_save_to(TXML *xml, const char *filename)
  137. {
  138.         char *encoding = xml->encoding ? xml->encoding : (char *)xml->doc->encoding;
  139.         return xmlSaveFormatFileEnc(filename, xml->doc, encoding, XML_SAVE_FORMAT) ? -1 : 0;
  140. }
  141. int xml_save(TXML *xml)
  142. {
  143.         char *encoding;
  144.         if (!xml->filename)
  145.         {
  146.                 errno = EINVAL;
  147.                 return -1;
  148.         }
  149.         encoding = xml->encoding ? xml->encoding : (char *)xml->doc->encoding;
  150.         return xmlSaveFormatFileEnc(xml->filename, xml->doc, encoding, XML_SAVE_FORMAT) ? -1 : 0;
  151. }
  152. int xml_save_close(TXML *xml)
  153. {
  154.         int ret;
  155.         int saveno;
  156.         ret = xml_save(xml);
  157.         saveno = errno;
  158.         xml_close(xml);
  159.         errno = saveno;
  160.         return ret;
  161. }
  162. int xml_select_nodes(TXML *xml, const char *xpath)
  163. {
  164.         xmlXPathContextPtr context;
  165.         if(!xml || !xpath)
  166.         {
  167.                 errno = EINVAL;
  168.                 return -1;
  169.         }
  170.         if (!(context = xmlXPathNewContext(xml->doc)))
  171.         {
  172.                 return -1;
  173.         }
  174.         if (xml->object)
  175.         {
  176.                 xmlXPathFreeObject(xml->object);
  177.         }
  178.         if (!(xml->object = xmlXPathEvalExpression(BAD_CAST(xpath), context)))
  179.         {
  180.                 goto err_context;
  181.         }
  182.         if (xmlXPathNodeSetIsEmpty(xml->object->nodesetval))
  183.         {
  184.                 goto err_object;
  185.         }
  186.         xmlXPathFreeContext(context);
  187.         return xml->object->nodesetval->nodeNr > 0 ? xml->object->nodesetval->nodeNr : 0;
  188. err_object:
  189.         xmlXPathFreeObject(xml->object);
  190.         xml->object = NULL;
  191. err_context:
  192.         xmlXPathFreeContext(context);
  193.         return 0;
  194. }
  195. char *xml_read_set_prop(TXML *xml, const int n, const char *name)
  196. {
  197.         TXMLStr *res;
  198.         if (!(xml && xml->object))
  199.         {
  200.                 errno = EINVAL;
  201.                 return NULL;
  202.         }
  203.         if (xmlXPathNodeSetIsEmpty(xml->object->nodesetval))
  204.         {
  205.                 errno = EINVAL;
  206.                 return NULL;
  207.         }
  208.         if (xml->object->nodesetval->nodeNr < n)
  209.         {
  210.                 errno = EINVAL;
  211.                 return NULL;
  212.         }
  213.         if (!xmlHasProp(xml->object->nodesetval->nodeTab[n], BAD_CAST(name)))
  214.         {
  215.                 errno = EINVAL;
  216.                 return NULL;
  217.         }
  218.         if (!(res = (TXMLStr *)malloc(sizeof(TXMLStr))))
  219.         {
  220.                 return NULL;
  221.         }
  222.         res->str = (char *)xmlGetProp(xml->object->nodesetval->nodeTab[n], BAD_CAST(name));
  223.         FIFO_PUSH(&xml->rubbish, res, node);
  224.         return res->str;
  225. }
  226. char *xml_read_set_content(TXML *xml, const int n)
  227. {
  228.         TXMLStr *res;
  229.         if (!(xml && xml->object))
  230.         {
  231.                 errno = EINVAL;
  232.                 return NULL;
  233.         }
  234.         if (xmlXPathNodeSetIsEmpty(xml->object->nodesetval))
  235.         {
  236.                 errno = EINVAL;
  237.                 return NULL;
  238.         }
  239.         if (xml->object->nodesetval->nodeNr < n)
  240.         {
  241.                 errno = EINVAL;
  242.                 return NULL;
  243.         }
  244.         if (!(res = (TXMLStr *)malloc(sizeof(TXMLStr))))
  245.         {
  246.                 return NULL;
  247.         }
  248.         res->str = (char *)xmlNodeGetContent(xml->object->nodesetval->nodeTab[n]);
  249.         FIFO_PUSH(&xml->rubbish, res, node);
  250.         return res->str;
  251. }
  252. int xml_write_set_prop(TXML *xml, const int n, const char *name, const char *value)
  253. {
  254.         if (!(xml && xml->object))
  255.         {
  256.                 errno = EINVAL;
  257.                 return -1;
  258.         }
  259.         if (xmlXPathNodeSetIsEmpty(xml->object->nodesetval))
  260.         {
  261.                 errno = EINVAL;
  262.                 return -1;
  263.         }
  264.         if (xml->object->nodesetval->nodeNr < n)
  265.         {
  266.                 errno = EINVAL;
  267.                 return -1;
  268.         }
  269.         if (!xmlHasProp(xml->object->nodesetval->nodeTab[n], BAD_CAST(name)))
  270.         {
  271.                 errno = EINVAL;
  272.                 return -1;
  273.         }
  274.         xmlSetProp(xml->object->nodesetval->nodeTab[n], BAD_CAST(name), BAD_CAST(value));
  275.         return 0;
  276. }
  277. int xml_write_set_content(TXML *xml, const int n, const char *value)
  278. {
  279.         if (!(xml && xml->object))
  280.         {
  281.                 errno = EINVAL;
  282.                 return -1;
  283.         }
  284.         if (xmlXPathNodeSetIsEmpty(xml->object->nodesetval))
  285.         {
  286.                 errno = EINVAL;
  287.                 return -1;
  288.         }
  289.         if (xml->object->nodesetval->nodeNr < n)
  290.         {
  291.                 errno = EINVAL;
  292.                 return -1;
  293.         }
  294.         xmlNodeSetContent(xml->object->nodesetval->nodeTab[n], BAD_CAST(value));
  295.         return 0;
  296. }
  297. char *xml_read_item_prop(TXML *xml, const char *xpath, const char *name)
  298. {
  299.         return xml_select_nodes(xml, xpath) > 0 ? xml_read_set_prop(xml, 0, name) : NULL;
  300. }
  301. char *xml_read_item_content(TXML *xml, const char *xpath)
  302. {
  303.         return xml_select_nodes(xml, xpath) > 0 ? xml_read_set_content(xml, 0) : NULL;
  304. }
  305. int xml_write_item_prop(TXML *xml, const char *xpath, const char *name, const char *value)
  306. {
  307.         return xml_select_nodes(xml, xpath) > 0 ? xml_write_set_prop(xml, 0, name, value) : -1;
  308. }
  309. int xml_write_item_content(TXML *xml, const char *xpath, const char *value)
  310. {
  311.         return xml_select_nodes(xml, xpath) > 0 ? xml_write_set_content(xml, 0, value) : -1;
  312. }
  313. static int xml_add_node(xmlNodePtr (*add)(xmlNodePtr, xmlNodePtr), TXML *xml, const char *xpath,
  314.                 const char *node_name, va_list ap)
  315. {
  316.         xmlNodePtr node;
  317.         char *str = NULL, *name = NULL;
  318.         if (xml_select_nodes(xml, xpath) != 1)
  319.         {
  320.                 return -1;
  321.         }
  322.         node = xmlNewNode(NULL, BAD_CAST(node_name));
  323.         while ((str = va_arg(ap, char *)))
  324.         {
  325.                 if (!name)
  326.                 {
  327.                         name = str;
  328.                 }
  329.                 else
  330.                 {
  331.                         xmlSetProp(node, BAD_CAST(name), BAD_CAST(str));
  332.                         name = NULL;
  333.                 }
  334.         }
  335.         if (name)
  336.         {
  337.                 xmlNodeSetContent(node, BAD_CAST(name));
  338.         }
  339.         return add(xml->object->nodesetval->nodeTab[0], node) ? 0 : -1;
  340. }
  341. int xml_add_child(TXML *xml, const char *xpath, const char *name, ...)
  342. {
  343.         int ret;
  344.         va_list ap;
  345.         va_start(ap, name);
  346.         ret = xml_add_node(xmlAddChild, xml, xpath, name, ap);
  347.         va_end(ap);
  348.         return ret;
  349. }
  350. int xml_add_prev_sibling(TXML *xml, const char *xpath, const char *name, ...)
  351. {
  352.         int ret;
  353.         va_list ap;
  354.         va_start(ap, name);
  355.         ret = xml_add_node(xmlAddPrevSibling, xml, xpath, name, ap);
  356.         va_end(ap);
  357.         return ret;
  358. }
  359. int xml_add_next_sibling(TXML *xml, const char *xpath, const char *name, ...)
  360. {
  361.         int ret;
  362.         va_list ap;
  363.         va_start(ap, name);
  364.         ret = xml_add_node(xmlAddNextSibling, xml, xpath, name, ap);
  365.         va_end(ap);
  366.         return ret;
  367. }
  368. int xml_add_sibling(TXML *xml, const char *xpath, const char *name, ...)
  369. {
  370.         int ret;
  371.         va_list ap;
  372.         va_start(ap, name);
  373.         ret = xml_add_node(xmlAddSibling, xml, xpath, name, ap);
  374.         va_end(ap);
  375.         return ret;
  376. }
  377. int xml_remove(TXML *xml, const char *xpath)
  378. {
  379.         int i, n;
  380.         xmlNodePtr tempNode, curNode;
  381.         if ((n = xml_select_nodes(xml, xpath)) <= 0)
  382.         {
  383.                 return -1;
  384.         }
  385.         for (i = 0; i < n; ++i)
  386.         {
  387.                 curNode = xml->object->nodesetval->nodeTab[i];
  388.                 tempNode = curNode->next;
  389.                 xmlUnlinkNode(curNode);
  390.                 xmlFreeNode(curNode);
  391.                 curNode = tempNode;
  392.         }
  393.         if (xml->object)
  394.         {
  395.                 xmlXPathFreeObject(xml->object);
  396.                 xml->object = NULL;
  397.         }
  398.         return 0;
  399. }
  400. // vim: ts=8 sw=8 expandtab