VS2010 MFC窗口程序 pugixml读写XML


       为了用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

猜你喜欢

转载自blog.csdn.net/l198738655/article/details/80340988