通过libxml2更新XML的属性值和元素值

场景:
1.有时候配置软件的全局设置项时,需要用到键值对的存储方式。
2.配置信息不多的情况下.数据库太重量级,文本文件对utf8编码又不好,即中文内容,这时候XML文件是最佳选择。
 
//这里使用的是libxml2-2.7.1版本库
 
#include <iostream>
#include <string.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/parserInternals.h>
#include <libxml/HTMLparser.h>
#include <libxml/HTMLtree.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
#include <libxml/debugXML.h>
#include <libxml/xmlerror.h>
#include "libxml/encoding.h"
//#include <tchar.h>

using namespace std;

void UpdateNodeValue(xmlNode* node, const char *value)
{
    xmlChar *xml_value = xmlCharStrdup(value);
    xmlNodeSetContent(node, xml_value);
    xmlFree(xml_value);
}

void UpdateAttrValue(xmlNode* node, const char *attr_name, const char *value)
{
    xmlChar *xml_prop_name = xmlCharStrdup(attr_name);
    xmlChar *xml_prop_value = xmlCharStrdup(value);
    xmlSetProp(node, xml_prop_name, xml_prop_value);
    xmlFree(xml_prop_value);
    xmlFree(xml_prop_name);
}

xmlXPathObjectPtr GetXPathObject(xmlDocPtr doc, const char* key)
{
    //获取xpath上下文
    xmlXPathContextPtr context = xmlXPathNewContext(doc);
    if (!context)
    {
        return NULL;
    }
    
    //获取xpath对象指针
    xmlChar *xml_key = xmlCharStrdup(key);
    xmlXPathObjectPtr result = xmlXPathEvalExpression(xml_key, context);
    xmlFree(xml_key);

    //释放xpath上下文
    xmlXPathFreeContext(context);

    //
    if (!result)
    {
        return NULL;
    }
    //结果为空
    if (!result || xmlXPathNodeSetIsEmpty(result->nodesetval))
    {
        return NULL;
    }

    return result;
}

//更新结点内容
void UpdateXmlNodeValue(xmlDocPtr doc, const char *key, const char *value)
{
    xmlXPathObjectPtr result = GetXPathObject(doc, key);
    if (!result)
    {
        return;
    }
    xmlNodeSetPtr nodeset = result->nodesetval;
    for (int i = 0; i < nodeset->nodeNr; i++)
    {
        //更新结点值
        UpdateNodeValue(nodeset->nodeTab[i], value);
    }
    xmlXPathFreeObject(result);
}

//更新结点属性值
void UpdateXmlNodeAttr(xmlDocPtr doc, const char *key, const char *attr_name, const char *value)
{
    xmlXPathObjectPtr result = GetXPathObject(doc, key);
    if (!result)
    {
        return;
    }
    
    xmlNodeSetPtr nodeset = result->nodesetval;
    for (int i = 0; i < nodeset->nodeNr; i++)
    {
        UpdateAttrValue(nodeset->nodeTab[i], attr_name, value);
    }
    xmlXPathFreeObject(result);
}

xmlDocPtr BeginUpdate(const char *xml_path)
{
    xmlInitParser();

    xmlDocPtr doc = xmlParseFile(xml_path);
    return doc;
}

void EndUpdate(xmlDocPtr doc, const char *out_path)
{
    xmlSaveFileEnc(out_path, doc, "UTF-8");
    xmlFreeDoc(doc);
    xmlCleanupParser();
}

int main(int argc, char** argv)
{

    xmlDocPtr doc = BeginUpdate("test.xml");
//    UpdateXmlNodeValue(doc, "//toolbarwindow[@name]", "goodbye");
    UpdateXmlNodeValue(doc, "//selectwindow", "goodbye");
    UpdateXmlNodeAttr(doc, "//toolbarwindow/rect[@x]", "x","100");

    EndUpdate(doc, "out.xml");

    return 0;
}


//测试例子[test.xml]

<xml>
<selectwindow>It is a select object window</selectwindow>
<toolbarwindow name="toolbar" width="200">
It is a toolbar.
<rect x="4" y="5"/>
</toolbarwindow >
</xml>


 

运行结果[out.xml]:

<?xml version="1.0" encoding="UTF-8"?>
<xml>
<selectwindow>goodbye</selectwindow>
<toolbarwindow name="toolbar" width="200">
It is a toolbar.
<rect x="100" y="5"/>
</toolbarwindow>
</xml>


 

问题:

如果这程序执行这条语句:UpdateXmlNodeValue(doc, "//toolbarwindow[@name]", "goodbye");

结果为:

<?xml version="1.0" encoding="UTF-8"?>
<xml>
<selectwindow>goodbye</selectwindow>
<toolbarwindow name="toolbar" width="200">goodbye</toolbarwindow>
</xml>

里面的<rect x="4" y="5"/>也被删除了.有兴趣的可以修改这个问题

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值