使用libxml2实现简单合并两个不同的xml文件
2012-07-08 16:37
1141 查看
读取两个不同的xml文件,然后从一个xml文件上获取一个节点,让它脱离原来的xml文件,接着将它驳接到另外一个xml文件上去。
可能会遇到的问题:驳接之后,如果对刚驳接进去的节点执行脱离+删除操作的话,会出现莫名的内存出错信息。然而未驳接过的节点直接删除是没问题的。就大概知道为什么会出错了。大概原因是xml文件的节点存储跟xmlDoc有关,如字典缓冲等,就如libxml(http://blog.csdn.net/shanzhizi)的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
*/
说明节点保存的内容不一定只限定存储在一个节点上,可能跟其他有关,关于该问题的详细描述请参考:http://blog.csdn.net/shanzhizi/article/details/7726743。
然后如果对每个xmlDoc读取的时候限制为XML_PARSE_NOBLANKS | XML_PARSE_NODICT,而且两个xmlDoc保证都是这样,即可实现xml文件的简单合并。如果下面的代码去掉这两个限制的话,立刻会在释放的时候出现错误。
合并的代码如下:
#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格式的节点字符串合并到一个xml文件中的根节点下的例子,下面这个程序编译通过可以正常使用。
int LinkXmlNodes(const char *pXMLFilePath)
{
xmlDocPtr doc; //定义解析文档指针
xmlDocPtr doc2;
xmlNodePtr curNode; //定义结点指针(你需要它为了在各个结点间移动)
xmlNodePtr curNode2;
const char *szDocName = pXMLFilePath;
char sXmlString[]="<igmp><status>1</status><group><id>1</id></group></igmp>";
//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://blog.csdn.net/shanzhizi
可能会遇到的问题:驳接之后,如果对刚驳接进去的节点执行脱离+删除操作的话,会出现莫名的内存出错信息。然而未驳接过的节点直接删除是没问题的。就大概知道为什么会出错了。大概原因是xml文件的节点存储跟xmlDoc有关,如字典缓冲等,就如libxml(http://blog.csdn.net/shanzhizi)的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
*/
说明节点保存的内容不一定只限定存储在一个节点上,可能跟其他有关,关于该问题的详细描述请参考:http://blog.csdn.net/shanzhizi/article/details/7726743。
然后如果对每个xmlDoc读取的时候限制为XML_PARSE_NOBLANKS | XML_PARSE_NODICT,而且两个xmlDoc保证都是这样,即可实现xml文件的简单合并。如果下面的代码去掉这两个限制的话,立刻会在释放的时候出现错误。
合并的代码如下:
#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格式的节点字符串合并到一个xml文件中的根节点下的例子,下面这个程序编译通过可以正常使用。
int LinkXmlNodes(const char *pXMLFilePath)
{
xmlDocPtr doc; //定义解析文档指针
xmlDocPtr doc2;
xmlNodePtr curNode; //定义结点指针(你需要它为了在各个结点间移动)
xmlNodePtr curNode2;
const char *szDocName = pXMLFilePath;
char sXmlString[]="<igmp><status>1</status><group><id>1</id></group></igmp>";
//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://blog.csdn.net/shanzhizi
相关文章推荐
- java实现两个不同list对象合并后并排序
- linux下使用libxml2实现对xml文件的读取及查询
- 使用Excel的VLOOKUP函数合并不同Sheet页两个表格中的相同项
- 在NET 1.1中合并两个DataTable的简单实现
- 使用不同的方法结合/合并两个JS数组
- JavaScript简单实现合并两个Json对象的方法示例
- 记一次项目经历——linux环境下使用libxml2实现xml文件的生成与解析
- 使用不同的方法结合/合并两个JS数组
- C#中使用Lambda表达式自定义比较器实现两个列表合并实例
- ActionBar简单使用——添加搜索按钮;让不同的Activity上显示不同的ActionBar;添加Tab标签;实现DrawerLayout并用ActionBarDrawerToggle控制
- linux下使用libxml2实现对xml文件的读取及查询
- 使用Kotlin实现Android简单Demo,对比JAVA实现分析具体语法不同之处(一)
- 简单的使用自动化技术实现用WORD读取一个XML文件的过程~
- 在NET 1.1中合并两个DataTable的简单实现
- day01之合并两个有序链表+实现1+2+3...+n要求不能使用乘除法循环条件判断等
- SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论 SignalR 简单示例 通过三个DEMO学会SignalR的三种实现方式 SignalR推送框架两个项目永久连接通讯使用 SignalR 集线器简单实例2 用SignalR创建实时永久长连接异步网络应用程序
- 17_7_13:合并两个有序链表。实现1+2+3+...+n,不使用常规方法
- 两个简单的数据库操作函数,避免对不同的表结构使用不同的update语句
- 12-界面控件之listView使用java代码和xml文件不同方式实现列表显示
- 使用两个栈来实现一个队列简单的push和pop