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

本文介绍了一个使用libxml2库更新XML文件中特定节点值及属性的C++程序实例。通过XPath表达式定位到目标节点,并更新其内容或属性。演示了如何读取XML文件、更新节点内容以及保存更改。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

场景:
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"/>也被删除了.有兴趣的可以修改这个问题

如果需要源码可以发送邮件到sdiwen1982@sohu.com索取 /*************************************** 功能:读取xml文件 参数:[in] xml文件路径 返回:true读取成功 false读取失败 **************************************/ bool ReadXml(CString sXmlPath /*xml文件路径*/); /*************************************** 功能:写入xml文件 参数:[in] xml文件路径 返回:true写入成功 false写入失败 **************************************/ bool WriteXml(CString sXmlPath /*xml文件路径*/); /*************************************** 功能:释放空间 参数:无 返回:无 **************************************/ void Release(); /*************************************** 功能:删除指定的节点 参数:无 返回:true删除成功 false删除失败 **************************************/ bool DeleteNode(); /*************************************** 功能:删除当前节点的所有子节点,当前节点不删除 参数:无 返回:true删除成功 false删除失败 **************************************/ bool DeleteAllSon(); /*************************************** 功能:根据索引删除子节点 参数:无 返回:true删除成功 false删除失败 **************************************/ bool DeleteSonByIndex(unsigned int nIndex); /*************************************** 功能:删除节点所有属性 参数:无 返回:true删除成功 false删除失败 **************************************/ bool DeleteAllAttr(); /*************************************** 功能:根据属性名删除属性 参数:无 返回:true删除成功 false删除失败 **************************************/ bool DeleteAttrByName(CString sName); /*************************************** 功能:根据索引删除属性 参数:无 返回:true删除成功 false删除失败 **************************************/ bool DeleteAttrByIndex(unsigned int nIndex); /*************************************** 功能:根据属性名设置属性值 参数:[in] sName 属性名 [in] sValue 属性值 返回:true设置成功 false设置失败 **************************************/ bool SetAttrValueByName(CString sName, CString sValue); /*************************************** 功能:插入属性 参数:[in] sName 属性名 [in] sValue 属性值 返回:true插入成功 false插入失败 **************************************/ bool InsertAttr(CString sName, CString sValue); /*************************************** 功能:设置节点 参数:[in] sValue 属性值 返回:true设置节点成功 false设置节点失败 **************************************/ bool SetNodeValue(CString sValue); /*************************************** 功能:插入子节点 参数:[in] sName 节点名 返回:非空表示插入节点成功,返回插入的新节点指针 空表示插入失败 **************************************/ CXMLNode * InsertNode(CString sName); /*************************************** 功能:判断是否存在子节点 参数:[in] pNode 子节点文件指针, 返回:false没有子节点 true有子节点 **************************************/ bool HasChild(MSXML2::IXMLDOMNodePtr pNode);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值