博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用libxml2实现简单合并两个不同的xml文件
阅读量:4055 次
发布时间:2019-05-25

本文共 2432 字,大约阅读时间需要 8 分钟。

读取两个不同的xml文件,然后从一个xml文件上获取一个节点,让它脱离原来的xml文件,接着将它驳接到另外一个xml文件上去。

       可能会遇到的问题:驳接之后,如果对刚驳接进去的节点执行脱离+删除操作的话,会出现莫名的内存出错信息。然而未驳接过的节点直接删除是没问题的。就大概知道为什么会出错了。大概原因是xml文件的节点存储跟xmlDoc有关,如字典缓冲等,就如libxml()的xmlFreeNode函数的里面的注释:
/*
     * When a node is a text node or a comment, it uses a global static
     * variable for the name of the node.
     * Otherwise the node name might come from the document's dictionnary
     */
说明节点保存的内容不一定只限定存储在一个节点上,可能跟其他有关,关于该问题的详细描述请参考:。
然后如果对每个xmlDoc读取的时候限制为XML_PARSE_NOBLANKS | XML_PARSE_NODICT,而且两个xmlDoc保证都是这样,即可实现文件的简单合并。如果下面的代码去掉这两个限制的话,立刻会在释放的时候出现错误。
合并的代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
int main(void) {
 xmlDoc *doc = NULL;
 char *fileName = "test1.xml";
    /*parse the file and get the DOM */
    doc = xmlReadFile(fileName, NULL, XML_PARSE_NOBLANKS | XML_PARSE_NODICT);
    if (doc == NULL) {
        printf("error: could not parse file %s", fileName);
        return -1;
    }
  
    xmlDoc *doc2 = xmlReadFile(“test2.xml", NULL, XML_PARSE_NOBLANKS | XML_PARSE_NODICT);
    xmlNodePtr second = xmlDocGetRootElement(doc2)->children;
    xmlUnlinkNode(second);
 
 xmlNodePtr root = xmlDocGetRootElement(doc);
 xmlAddChild(root, second);
 //xmlUnlinkNode(second);
 xmlFreeNode(second);
 xmlFreeDoc(doc);
 xmlFreeDoc(doc2);

}

上面这个程序没有保存,所以其实什么也没有做。

下面提供一个将一个格式的节点字符串合并到一个xml文件中的根节点下的例子,下面这个程序编译通过可以正常使用。

int LinkXmlNodes(const char *pXMLFilePath){	xmlDocPtr doc;   //定义解析文档指针	xmlDocPtr doc2;	xmlNodePtr curNode;  //定义结点指针(你需要它为了在各个结点间移动)	xmlNodePtr curNode2;	const char *szDocName = pXMLFilePath;	char sXmlString[]="
1
1
"; //szDocName = pXMLFilePath; doc = xmlReadFile(szDocName,"GB2312",XML_PARSE_NOBLANKS | XML_PARSE_NODICT); //解析文件 if (NULL == doc){ fprintf(stderr,"Document not parsed successfully. \n"); return -1; } curNode = xmlDocGetRootElement(doc); if (NULL == curNode){ fprintf(stderr,"empty document\n"); xmlFreeDoc(doc); return -1; } doc2 =xmlReadMemory( sXmlString, strlen(sXmlString), "noname.xml","GB2312",XML_PARSE_NOBLANKS | XML_PARSE_NODICT); if (NULL == doc2){ fprintf(stderr,"Document not parsed successfully. \n"); return -1; } curNode2 = xmlDocGetRootElement(doc2); if (NULL == curNode2){ fprintf(stderr,"empty document\n"); xmlFreeDoc(doc2); return -1; } xmlUnlinkNode(curNode2); xmlAddChild(curNode,curNode2); xmlSaveFormatFileEnc(szDocName, doc,"GB2312",1); xmlFreeDoc(doc); xmlFreeDoc(doc2); return 0;}

来自:

转载地址:http://epoci.baihongyu.com/

你可能感兴趣的文章
cppcheck c++静态代码检查
查看>>
在C++中使用Lua
查看>>
socket编程中select的使用
查看>>
关于无人驾驶的过去、现在以及未来,看这篇文章就够了!
查看>>
所谓的进步和提升,就是完成认知升级
查看>>
为什么读了很多书,却学不到什么东西?
查看>>
长文干货:如何轻松应对工作中最棘手的13种场景?
查看>>
如何用好碎片化时间,让思维更有效率?
查看>>
No.174 - LeetCode1305 - 合并两个搜索树
查看>>
No.175 - LeetCode1306
查看>>
No.176 - LeetCode1309
查看>>
No.182 - LeetCode1325 - C指针的魅力
查看>>
mysql:sql alter database修改数据库字符集
查看>>
mysql:sql truncate (清除表数据)
查看>>
yuv to rgb 转换失败呀。天呀。谁来帮帮我呀。
查看>>
yuv420 format
查看>>
yuv420 还原为RGB图像
查看>>
LED恒流驱动芯片
查看>>
驱动TFT要SDRAM做为显示缓存
查看>>
使用file查看可执行文件的平台性,x86 or arm ?
查看>>