为了用VC++读写XML文件前后弄了差不多5天了,试过微软自家的MSXML和libxml2库,介绍MSXML的相关书籍和CSDN博客里的文章基本全是XP时代的MSXML4.dll,WINDOWS 7 system32目录只有MSXML3.dll和新版的MSXML6.dll。查了3天资料,痛苦无比,还是无法使用,微软可能是为了更大的兼容考虑让VB之类的其他语言也能调用MSXML6.dll做了一些修改,弄得我一头包还是搞不定。试试其他第三方的库,一开始用了libxml2,介绍的文章给出的例子指针无限报错,说两个地方同时访问,百度一下说libxml2此库堆用得太多,虽然其自带析构函数,还是容易内存泄漏什么的,反正没办法用。万念俱灰打算认怂之下一定是春哥 曾哥听见了我内心无助的呼唤,忽然让我看到有人提到pugixml库,遂下来试试,去官网下了库文件编译后报错,说什么宏声明重复,坑死人啊,正打算放弃再试一把就认怂,此时一定是春哥 曾哥两位至高神又一次听见吾内心之呐喊,最后一次编译居然通过了,成功读出XML小节内的文本。赞美春哥,赞美春哥好兄弟曾哥!我们在天上的父,愿人都尊你的名为圣。 愿你的国降临。愿你的旨意行在地上,如同行在天上。我们日用的饮食,今日赐给我们。 免我们的债,如同我们免了人的债。不叫我们遇见试探, 救我们脱离凶恶。因为国度、权柄、荣耀,全是你的,直到永远!
首先去pugixml的官网下载库文件 https://pugixml.org/我下载的时候版本是1.9。
解压后再src目录下会看到pugiconfig.hpp pugixml.cpp pugixml.hpp 3个文件,它们就是pugixml的库文件了。大家肯定会奇怪怎么不是.h和.cpp文件,其实我也奇怪,百度了一下后说.hpp是把函数声明和函数实现写到一个文件里了,这就是.hpp。然后又说只需要引入pugixml.hpp这个文件就行,其他两个可以不管,我照着做了,要么就提示没声明的标识符,都引入就提示说什么宏重复定义,让人崩溃,实际上pugixml.cpp里还是放着具体的函数实现,不引入还是不行的,那么到底要怎么做才对呢?
需要在pugixml.cpp文件头部加入:#include "stdafx.h"再编译就能通过了,调用函数也正常了。XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<newNode1>chun_ge</newNode1>
<newNode2>newNode2 content</newNode2>
<newNode3>newNode3 content</newNode3>
<node2 attribute="yes">NODE CONTENT</node2>
<son>
<grandson>This is a grandson node</grandson>
</son>
</root>
读取节点中的文本:
CString nsib;
xml_document doc; //创建一个DOC指针
xml_parse_result result = doc.load_file(_T("C:\\zengge.xml"));
xml_node price= doc.child("root");
string respo=price.child_value("newNode1");
nsib=respo.c_str();
OutputDebugStringW(nsib+L"\n");
修改一个已存在的节点里的文本:
CString nsib;
xml_document doc; //创建一个DOC指针
xml_parse_result result = doc.load_file(_T("C:\\zengge.xml"));
xml_node price= doc.child("root"); //选中根节点
price.child("newNode1").first_child().set_value("zeng_ge");
string respo=price.child_value("newNode1");
nsib=respo.c_str();
OutputDebugStringW(nsib+L"\n");
//修改完后保存
doc.save_file("C:\\zengge.xml","\t",pugi::format_no_escapes,pugi::encoding_utf8) ;
以上修改的都是根节点下的子节点,下面这个是修改子节点下的孙节点里的文本:
CString nsib;
xml_document doc; //创建一个DOC指针
xml_parse_result result = doc.load_file(_T("C:\\zengge.xml"));
xml_node price= doc.child("root"); //选中根节点
price.child("son").child("grandson").first_child().set_value("zeng_ge");
string respo=price.child_value("newNode1");
nsib=respo.c_str();
OutputDebugStringW(nsib+L"\n");
/*保存文件,这里特别要说明的一个问题就是参数的设置:pugi::format_no_escapes。设置成这样才能正确输出特殊符号"<,&"等*/
doc.save_file("C:\\zengge.xml","\t",pugi::format_no_escapes,pugi::encoding_utf8) ;
读出节点内的属性:
CString nsib;
xml_document doc; //创建一个DOC指针
xml_parse_result result = doc.load_file(_T("C:\\zengge.xml"));
xml_node price= doc.child("root").child("node2"); //选中根节点下的node2节点
string respo=price.attribute("attribute").value(); //读出node2的属性值
nsib=respo.c_str();
OutputDebugStringW(nsib+L"\n");
修改节点内的属性:
CString nsib;
xml_document doc; //创建一个DOC指针
xml_parse_result result = doc.load_file(_T("C:\\zengge.xml"));
xml_node price= doc.child("root").child("node2"); //选中根节点
xml_attribute attr=price.attribute("attribute"); //这里得换个类型
attr.set_value("123"); //把attribute的值修改为123
doc.save_file("C:\\zengge.xml","\t",pugi::format_no_escapes,pugi::encoding_utf8) ;
关于存储中文:
此库默认编码UTF-8默认是支持中文的,但是还是有一些小技巧,新建XML的时候比如用TXT格式另存为XML的时候默认编码需要是ANSI,然后保存的时候按照上面例子中的参数保存,正常打开读取的时候就能正常读取到中文,保存后也会是正常的中文。
示例工程:https://download.csdn.net/download/l198738655/10424856