• 3734阅读
  • 4回复

[提问]急求教关于解析超大XML文件 [复制链接]

上一主题 下一主题
离线eric584930
 

只看楼主 倒序阅读 楼主  发表于: 2015-04-13
关键词: XML解析器

请教解析超大型xml(>=1G)有啥好的方法或者开源解析器?用C/C++/Qt,重视效率,一般的SAX太慢
本帖提到的人: @XChinux
生活就是这样
离线zgfree

只看该作者 1楼 发表于: 2015-04-13
如果xml内容格式固定的话,写一个专有解析器,会快很多
离线dosmlp

只看该作者 2楼 发表于: 2015-04-13
为什么这么大,不能分开存储吗
离线stlcours

只看该作者 3楼 发表于: 2015-04-13
XML不是给你们这样用的。自找麻烦。
离线begboy

只看该作者 4楼 发表于: 2015-04-13
eric584930,您好!
     解析XML文件的方法很多,目前较为流行的有DOM4J、SAX、JDOM和DOM。
但如果您文件超大,且需采用C/C++语言处理,建议直接使用libxml2库。
虽然QT有处理XML模块,但基于您快速和超大的原因,真心不建议您使用QT。
其实涉及底层硬件或高速处理(实时)等方面,QT不是一个合适的工具。

以下是转贴内容,尽管有部分错误,但仍值得您去参考:



在C语言中解析XML文件,需要先安装libxml2的开发包,使用下面命令安装
sudo apt-get install libxml++1.0-dev

sudo apt-get install libxml++1.0-doc



安装完之后包含头文件<libxml/parser.h>就可以在C里面使用libxml2库了。
int xmlKeepBlanksDefault (int val)//设置是否忽略空白节点,比如空格,在分析前必须调用,默认值是0,最好设置成1.否则会有惨痛的调试经历...

xmlDocPtr xmlReadFile (const char * filename)//分析一个xml文件,并返回一个文档对象指针
//xml操作的基础结构提及其指针类型

xmlDoc, xmlDocPtr 文档对象的结构体及其指针 xmlNode xmlNodePtr节点对象的结构体及其指针 xmlAttr xmlAttrPtr 节点属性的结构体及其指针 xmlNs xmlNsPtr节点命名空间的结构及其指针


//根节点相关函数
xmlNodePtrxmlDocGetRootElement (xmlDocPtr doc) //获取文档根节点xmlNodePtrxmlDocSetRootElement (xmlDocPtr doc, xmlNodePtr root)//设置文档根节点


//创建子节点相关函数
xmlNodePtrxmlNewNode (xmlNsPtr ns, const xmlChar * name)//创建新节点 xmlNodePtrxmlNewChild (xmlNodePtr parent, xmlNsPtr ns,const xmlChar * name, constxmlChar * content) //创建新的子节点 xmlNodePtrxmlCopyNode(const xmlNodePtr node, int extended)//复制当前节点


//添加子节点相关函数
xmlNodePtrxmlAddChild (xmlNodePtr parent, xmlNodePtrcur) //给指定节点添加子节点 xmlNodePtrxmlAddNextSibling (xmlNodePtr cur,xmlNodePtr elem) //添加后一个兄弟节点xmlNodePtr xmlAddPrevSibling(xmlNodePtrcur, xmlNodePtr elem) //添加前一个兄弟节点 xmlNodePtrxmlAddSibling (xmlNodePtrcur, xmlNodePtr elem)//添加兄弟节点

//属性相关函数
xmlAttrPtrxmlNewProp (xmlNodePtr node, const xmlChar *name, const xmlChar *value) //创建新节点属性 xmlChar * xmlGetProp(xmlNodePtr node, const xmlChar *name) //读取节点属性 xmlAttrPtrxmlSetProp(xmlNodePtr node, const xmlChar * name, const xmlChar *value) //设置节点属性
在文档解析完之后,需要调用xmlFreeDoc(xmlDocPtr)去释放资源,
而通过xmlNodeGetContent(), xmlGetProp()所读到的内容跟属性在用完之后,需要调用xmlFree()去释放所当用的资源。



libxml自定义了一个字符类型xmlChar,其本质是 unsigned char.
另外,libxml提供了一个宏来将char*转换成xmlChar*, 名字很有趣,叫 BAD_CAST 它的本质其实是unsigned char*.
为了方便对xmlChar类型字符串的操作,libxml提供了自己的函数,它们的定义于标准c函数库中的字符串函数很像.
xmlChar* xmlStrcat (xmlChar *cur, const xmlChar * add)
const xmlChar *xmlStrchr(const xmlChar * str, xmlChar val)
int xmlStrcmp (const xmlChar * str1, const xmlChar * str2)
int xmlStrlen (const xmlChar * str)
xmlChar *xmlStrncat (xmlChar * cur, const xmlChar * add, intlen)
int xmlStrncmp (const xmlChar * str1, const xmlChar * str2, intlen)
const xmlChar *xmlStrstr (const xmlChar * str, const xmlChar *val)
相信这些函数大家都看得眼熟,这里就不一一解释了.
更多函数大家可以参考
http://xmlsoft.org/html/libxml-xmlstring.html

下面是一个读出所有属性跟内容的例子,
编译命令(需要加入库跟头文件目录):gcc test.c -o test -lxml2 -I/usr/include/libxml2



[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <unistd.h>  
  3. #include <sys/types.h>  
  4.   
  5. #include <libxml/parser.h>  
  6. #include <libxml/xmlmemory.h>  
  7. /////////////////////////////////////////////////  
  8. int main(int argc, char **argv) {  
  9.     xmlDocPtr doc;  
  10.     xmlNodePtr curNode;  
  11.     xmlChar *szKey, *szAttr;  
  12.     xmlAttrPtr attrPtr;  
  13.     int count = 0;  
  14.     char szFile[512], szBuf[1024], key[256];  
  15.       
  16.       
  17.     sprintf(szFile, "./test.xml");  
  18.     doc = xmlReadFile(szFile, "UTF-8", XML_PARSE_RECOVER);  
  19.     if (NULL == doc) {  
  20.         fprintf(stderr, "open file failed!\n");  
  21.         return -1;  
  22.     }  
  23.   
  24.     curNode = xmlDocGetRootElement(doc);  
  25.     if (NULL == curNode) {  
  26.         fprintf(stderr, "Document not parsed sucessfully!\n");  
  27.         xmlFreeDoc(doc);  
  28.         return -1;  
  29.     }  
  30.   
  31.     printf("root name: %s\n", curNode->name);  
  32.     curNode = curNode->xmlChildrenNode;  
  33.     while (curNode != NULL) {  
  34.         count++;  
  35.         szKey = xmlNodeGetContent(curNode);     // get the content  
  36.         printf("%s\t", curNode->name);  
  37.         attrPtr = curNode->properties;  
  38.         while (attrPtr != NULL) {  
  39.             szAttr = xmlGetProp(curNode, BAD_CAST attrPtr->name);  
  40.             printf("%s:%s\t", attrPtr->name, szAttr);  
  41.             strcpy(key, szAttr);  
  42.             xmlFree(szAttr);  
  43.             attrPtr = attrPtr->next;  
  44.         }  
  45.         printf("%s\t", szKey);  
  46.         xmlFree(szKey);  
  47.           
  48.         curNode = curNode->next;  
  49.     }  
  50.   
  51.     xmlFreeDoc(doc);  
  52.       
  53.     return 0;  
  54. }  

快速回复
限100 字节
 
上一个 下一个