libxml教程

缘起

我的CloudBox需要一个跨平台的方案来解决iOS上以及Android上的xml档案读取问题

因为游戏总是需要储存一些设定值,或是过关存档之类的

但又不能轻易的使用iOS内建提供的或著是Java内建提供的函数,这样整起来会很麻烦

而且思考到以后增加新的平台,会有不小的困扰,最后决定就用libxml

libxml又是可以在windows环境下使用的,因此直接用visual studio也可以轻易尝试学习API如何使用

环境简介

操作系统: Windows XP

IDE工具: Visual Studio 2008

工程类型: Visual C++ Win32 Console Application


下载连结

lib及.h档下载连结

http://xmlsoft.org/sources/win32/

dll下载连结

http://www.dll-files.com/dllindex/dll-files.shtml?iconv

http://www.dll-files.com/dllindex/dll-files.shtml?zlib1

http://www.dll-files.com/dllindex/dll-files.shtml?libxml2

设定说明图解

libxml教程_第1张图片

libxml教程_第2张图片

如图所示,我在工程目录中创建了两个文件夹,在libxml中放了iconv跟libxml的.h文档

另外也创建了lib档,将所有的lib都放进去

libxml教程_第3张图片

libxml教程_第4张图片

然后再项目工程中设定libaray的文件路经跟include的文件路径


代码说明

1. 读取XML文档

xmlDocPtr doc;
xmlNodePtr root;
// load an exist xml file.
doc = xmlParseFile("test.xml");
if (doc == NULL ) 
{ 
    fprintf(stderr,"Document not parsed successfully. \n"); 
    return 0; 
} 
// get root
root = xmlDocGetRootElement(doc);
if (root == NULL) 
{ 
    fprintf(stderr,"empty document\n"); 
    xmlFreeDoc(doc);
    return 0;
}


xmlDoc 是一个struct ,保存了一个xml 的相关信息,例如文件名、文档类型、子节点等等;xmlDocPtr 等于xmlDoc* ,它搞成这个样子总让人以为是智能指针,其实不是,要手动删除的。

xmlParseFile函数以默认方式读入一个UTF-8格式的文档,并返回文档指针。

xmlReadFile函数读入一个带有某种编码的xml文档,并返回文档指针;细节见libxml2参考手册。

xmlFreeDoc 释放文档指针。

xmlDocGetRootElement函数得到根节点curNode


2.建立XML文档

void CreateNewXMLDemo()
{
    // create xml document
    xmlDocPtr doc = xmlNewDoc(BAD_CAST"1.0");
    xmlNodePtr root = xmlNewNode(NULL,BAD_CAST"root");

    //set root
    xmlDocSetRootElement(doc,root);

    //add node
    xmlNewTextChild(root, NULL, BAD_CAST "newNode1", BAD_CAST "newNode1 content");
    xmlNewTextChild(root, NULL, BAD_CAST "newNode2", BAD_CAST "newNode2 content");
    xmlNewTextChild(root, NULL, BAD_CAST "newNode3", BAD_CAST "newNode3 content");

    //create node and add content

    xmlNodePtr node = xmlNewNode(NULL,BAD_CAST"node2");
    xmlNodePtr content = xmlNewText(BAD_CAST"NODE CONTENT");
    xmlAddChild(root,node);
    xmlAddChild(node,content);

    // add attribute
    xmlNewProp(node,BAD_CAST"attribute",BAD_CAST "yes");

    //create son and grandson

    node = xmlNewNode(NULL, BAD_CAST "son");
    xmlAddChild(root,node);
    xmlNewTextChild(node, NULL, BAD_CAST "grandson", BAD_CAST "grandson content");

    xmlNodePtr grandson = xmlNewNode(NULL, BAD_CAST "grandson2");
    xmlAddChild(node,grandson);
    xmlAddChild(grandson, xmlNewText(BAD_CAST "This is a grandson2 node"));

    //save xml

    int nRel = xmlSaveFile("test3.xml",doc);

    if (nRel != -1)
    {
        cout<<"create a xml:"<<nRel<<"bytes"<<endl;
    }

    //release

    xmlFreeDoc(doc);
}

libxml教程_第5张图片

xmlCharLibxml2中的字符类型,库中所有字符、字符串都是基于这个数据类型。事实上它的定义是:xmlstring.h

xmlNewDoc函数创建一个新的文档指针。

xmlNewNode可以创建一个新的节点

xmlDocSetRootElement可以将该节点设为根节点

xmlNewTextChild直接添加一个文本子节点

第二创建节点的方式是先创建新节点,然后用xmlAddChild将新节点加入上层节点。

xmlNewProp可以创建节点的属性

xmlSaveFile可以将xml存档

因为总是要在xmlChar*char*之间进行类型转换,所以定义了一个宏BAD_CAST,其定义如下:xmlstring.h

#define BAD_CAST (xmlChar *)


3.遍历节点,修改与删除

xmlNodePtr head = root->children->next;
while(head != NULL)
{
    if(head->type == XML_ELEMENT_NODE)
    {
        cout<<"Name:"<<head->name<<endl;
        cout<<"Content:"<<xmlNodeGetContent(head->children)<<endl;
        // update test05
        if ((!xmlStrcmp(head->name, (const xmlChar *)"test05")))
        {
            xmlNodeSetContent(head->children,(const xmlChar *)"orz05");
        }

        // remove node
        if (!xmlStrcmp(head->name, BAD_CAST "test07"))
        {
            xmlNodePtr tempNode;
            tempNode = head->next;
            xmlUnlinkNode(head);
            xmlFreeNode(head);
            head = tempNode;
            continue;
        }
    }
    head = head->next;
}

在libxml中只需要针对 XML_ELEMENT_NODE型态的节点进行搜索即可

xmlNodeGetContent可以取得节点的内文

xmlNodeSetContent可以设定节点的内文

可以透过xmlStrcmp来比较是否为要找的节点,xmlNodePtr的name属性则是节点名称,children则为内文节点

xmlUnlinkNode可以删除节点

libxml教程_第6张图片

完整工程下载

http://download.csdn.net/detail/cloudhsu/4382259

你可能感兴趣的:(xml,windows,null,application,文档,include)