1,编码时需要包括头文件:#include <libxml/globals.h>,编译时需要链接 -lxml2 -lwsock32 的库文件.
2,xmlexports.h需要修改部分代码才可以被正常连接,否则使用xmlfree函数时会报"_imp__xmlFree"的链接错误.
修改代码如下:
将 #if defined(_WIN32) && defined(__MINGW32__) 代码段,包括:
#if defined(_WIN32) && defined(__MINGW32__)
#undef XMLPUBFUN
#undef XMLPUBVAR
#undef XMLCALL
#if defined(IN_LIBXML) && !defined(LIBXML_STATIC)
#define XMLPUBFUN __declspec(dllexport)
#define XMLPUBVAR __declspec(dllexport)
#else
#define XMLPUBFUN
#if !defined(LIBXML_STATIC)
#define XMLPUBVAR __declspec(dllimport) extern
#else
#define XMLPUBVAR extern
#endif
#endif
#define XMLCALL __cdecl
#if !defined _REENTRANT
#define _REENTRANT
#endif
#endif
注释掉,然后在原有位置添上:
#if defined(_WIN32) && defined(__MINGW32__)
#define XMLPUBFUN
#ifdef __cplusplus
#define XMLPUBVAR extern
#else
#define XMLPUBVAR
#endif
#if !defined _REENTRANT
#define _REENTRANT
#endif
#endif
具体原因及详细信信息 http://mail.gnome.org/archives/xml/2004-February/msg00007.html
3,解析xml.
这里,我们以解析内容如下的xml文件为例:
"
<?xml version="1.0" encoding="UTF-8"?>
<NodeRoot ver = "000">
<Node1 ver = "111">
<Node2 ver = "222"/>
</Node1>
<Node3 ver = "333">
v3
<Node3/>
</NodeRoot>
"
首先,打开xml文件,使用:
XMLPUBFUN xmlDocPtr XMLCALL xmlParseFile (const char *filename); (libxml/parser.h)
获得xml的根节点,使用:
XMLPUBFUN xmlNodePtr XMLCALL xmlDocGetRootElement (xmlDocPtr doc);(libxml/tree.h)
例:
int ParseXMLFile(char *pXMLFileName)
// retval:
// 0 : Success
// -1: Error ,for xml file open
// -2: Error ,for xml file parse
{
int retval = 0;
xmlDocPtr doc = NULL;
xmlNodePtr cur = NULL;
doc = xmlParseFile(pXMLFileName);
if (doc == NULL )
{
fprintf(stderr,"XMLParser:Document not parsed successfully. \n");
retval = -1;
goto ERROR_RET;
}
cur = xmlDocGetRootElement(doc); // 会得到NodeRoot 节点.
if (cur == NULL)
{
fprintf(stderr,"XMLParser:Empty document.\n");
retval = -2;
goto ERROR_RET;
}
// ... do something
parsexml(doc,cur); // 定义见下面.
ERROR_RET:
if(doc != NULL)
xmlFreeDoc(doc);
return retval;
}
其中,:
结构xmlNodePtr 定义如下(libxml/tree.h):
typedef struct _xmlNode xmlNode;
typedef xmlNode *xmlNodePtr;
struct _xmlNode {
void *_private; /* application data */
xmlElementType type; /* type number, must be second ! */
const xmlChar *name; /* the name of the node, or the entity */
struct _xmlNode *children; /* parent->childs link */
struct _xmlNode *last; /* last child link */
struct _xmlNode *parent; /* child->parent link */
struct _xmlNode *next; /* next sibling link */
struct _xmlNode *prev; /* previous sibling link */
struct _xmlDoc *doc; /* the containing document */
/* End of common part */
xmlNs *ns; /* pointer to the associated namespace */
xmlChar *content; /* the content */
struct _xmlAttr *properties;/* properties list */
xmlNs *nsDef; /* namespace definitions on this node */
void *psvi; /* for type/PSVI informations */
unsigned short line; /* line number */
unsigned short extra; /* extra data for XPath/XSLT */
};
我们可以使用节点结构中的指针成员来遍历xml树中的各个节点.
我一般使用递归的方式遍历xml树:
int parsexml(xmlDocPtr doc, xmlNodePtr cur)
{
while (cur != NULL)
{
// do something about every node
printf("name: %s\n",cur->name);
{
// for example,we get the "ver" attribute of every node
xmlChar *uri = NULL;
uri = xmlGetProp(cur,(const xmlChar *) "ver");
if(uri != NULL)
{
printf("ver: %s\n", uri);
xmlFree(uri);
}
; // ... others
}
parsexml(doc,cur->xmlChildrenNode);
cur = cur->next;
}
return 0;
}
对于我们已经获取的结点,我们可以使用以下函数获取其各项属性各项属性:
XMLPUBFUN xmlChar * XMLCALL xmlGetProp (xmlNodePtr node,const xmlChar *name); (libxml/tree.h)
获得该节点的某项属性,其中,属性名称使用 第二个参数name指定,第一个参数需要传入结点指针.
属性的值通过函数返回传出,返回类型是 xmlChar,这里注意,返回的地址是指向堆的,这意味着你需要
在使用完毕后,手动释放这块内存.这里使用xmlfree函数,并将指针传入即可.
更多函数参见 libxml/tree.h
最后,你需要调用xmlFreeDoc函数进行必要的释放工作.
完整代码:
http://www.blogjava.net/Files/lixf/testlibxml.rar
posted on 2005-12-07 11:40
___ 阅读(1452)
评论(0) 编辑 收藏