VC++中操作XML(MFC、SDK)转
[转]VC++中操作XML(MFC、SDK)
XML在Win32程序方面应该没有在Web方面应用得多,很多Win32程序也只是用XML来存存配置信息而已,而且没有足够的好处的话还不如用ini。VC++里操作XML有两个库可以用:MSXML和XmlLite。MSXML又细分了两种接口:DOM和SAX2。XP没自带有XmlLite,只自带有2.x、3.x版的MSXML,不支持SAX2(需要MSXML 4.0以上),所以优先使用DOM。
DOM是以COM形式提供的,VC++里调用DOM可以分3种方法:
1、MFC里用CComPtr调用
2、SDK里直接调用DOM接口
3、SDK里用智能指针调用
这3种方法本质上是一样的,区别只不过在于需要编码的多少而已,用CComPtr可以极大的简化代码,下面是几个例子。
例子stocks.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <root>
- <node1>text1</node1>
- <node2>
- <childnode1 attrib1="value1" attrib2="value2"/>
- <childnode2 attrib1="value1" attrib2="value2">childtext1</childnode2>
- </node2>
- </root>
这个例子应该包含了XML最常见的特征了吧?
MFC
MFC里可以直接使用DOM,不需要手动添加额外的头文件,只需要在CWinApp::InitInstance()里调用CoInitialize(NULL)初始化COM,在CWinApp::ExitInstance里调用CoUninitialize()释放COM就行了。
//读取XML
- CComPtr<IXMLDOMDocument> spDoc; //DOM
- spDoc.CoCreateInstance(CLSID_DOMDocument);
- VARIANT_BOOL vb;
- spDoc->load(CComVariant(OLESTR("stocks.xml")), &vb); //加载XML文件
- CComPtr<IXMLDOMElement> spRootEle;
- spDoc->get_documentElement(&spRootEle); //根节点
- CComPtr<IXMLDOMNodeList> spNodeList;
- spRootEle->get_childNodes(&spNodeList); //子节点列表
- long nLen;
- spNodeList->get_length(&nLen); //子节点数
- for (long i = 0; i != nLen; ++i) //遍历子节点
- {
- CComPtr<IXMLDOMNode> spNode;
- spNodeList->get_item(i, &spNode);
- ProcessNode(spNode); //节点处理函数
- }
- //写入XML
- CComPtr<IXMLDOMNode> spNode;
- spRootEle->selectSingleNode(OLESTR("/root/node1"), &spNode);
- spNode->put_text(OLESTR("newText")); //写入text
- spRootEle->selectSingleNode(OLESTR("/root/node2/childnode1/@attrib1"), &spNode);
- spNode->put_nodeValue(CComVariant(OLESTR("newValue"))); //写入value
- CComPtr<IXMLDOMNode> spNewNode;
- spDoc->createNode(CComVariant(NODE_ELEMENT), OLESTR("childnode3"), OLESTR(""), &spNewNode); //创建新节点
- spRootEle->selectSingleNode(OLESTR("/root/node2"), &spNode);
- spNode->appendChild(spNewNode, &spNewNode); //将新节点加为node2的子节点
- spNewNode->put_text(OLESTR("childtext2")); //写入新节点text
- CComQIPtr<IXMLDOMElement> spEle = spNewNode; //注意这里使用CComQIPtr
- spEle->setAttribute(OLESTR("attrib1"), CComVariant(OLESTR("value1")));//给新节点添加属性
- spDoc->save(CComVariant(OLESTR("stocks.xml")));
- //节点处理函数
- void ProcessNode(CComPtr<IXMLDOMNode>& spNode)
- {
- CComBSTR bsNodeName;
- spNode->get_nodeName(&bsNodeName); //节点名
- AfxMessageBox(COLE2CT(bsNodeName));
- CComVariant varVal;
- spNode->get_nodeValue(&varVal); //节点值
- AfxMessageBox(COLE2CT(varVal.bstrVal));
- DOMNodeType eNodeType;
- spNode->get_nodeType(&eNodeType);
- if (eNodeType == NODE_ELEMENT) //只有NODE_ELEMENT类型才能包含有属性和子节点
- {
- //递归遍历节点属性
- CComPtr<IXMLDOMNamedNodeMap> spNameNodeMap;
- spNode->get_attributes(&spNameNodeMap);
- long nLength;
- spNameNodeMap->get_length(&nLength);
- for (long i = 0; i != nLength; ++i)
- {
- CComPtr<IXMLDOMNode> spNodeAttrib; //注意属性也是一个IXMLDOMNode
- spNameNodeMap->get_item(i, &spNodeAttrib);
- ProcessNode(spNodeAttrib);
- }
- //递归遍历子节点
- CComPtr<IXMLDOMNodeList> spNodeList;
- spNode->get_childNodes(&spNodeList);
- spNodeList->get_length(&nLength);
- for (long i = 0; i != nLength; ++i)
- {
- CComPtr<IXMLDOMNode> spChildNode;
- spNodeList->get_item(i, &spChildNode);
- ProcessNode(spChildNode);
- }
- }
- }
对于<tag>text</tag>这样的节点,get_nodeValue会得到空,要得到"text"的话可以遍历子节点(只有一个子节点,它的nodeName为"#text",nodeType为NODE_TEXT,nodeValue就是"text");也可以用get_text直接得到"text",但是对于这样的节点<tag>text<childtag>childtext</childtag></tag>,get_text会同时得到"text"和"childtext",不过这样的节点应该是不允许的。
DOM里使用的字符串(BSTR)都是OLESTR类型,默认情况下OLESTR是Unicode字符,MFC里可以用COLE2CT把LPCOLESTR转换为LPCTSTR。
对于自己定义的XML,大多数时候不需要遍历,可以通过调用selectNodes、selectSingleNode指定XPath直接读取某个节点或属性:
- CComPtr<IXMLDOMDocument> spDoc; //DOM
- spDoc.CoCreateInstance(CLSID_DOMDocument);
- VARIANT_BOOL vb;
- spDoc->load(CComVariant(OLESTR("stocks.xml")), &vb); //加载XML文件
- CComPtr<IXMLDOMElement> spRootEle;
- spDoc->get_documentElement(&spRootEle); //根节点
- CComPtr<IXMLDOMNodeList> spNodeList;
- CComPtr<IXMLDOMNode> spNode;
- spRootEle->selectNodes(OLESTR("/root/node2/*"), &spNodeList); //得到node2下的所有子节点
- spRootEle->selectSingleNode(OLESTR("/root/node2/childnode1/@attrib1"), &spNode); //得到childnode1的attrib1属性
XPath的语法可以参考XML文档或MSDN。
SDK
SDK中也可以使用智能指针,和MFC没太大区别,同样很方便,直接给代码:
- #include <iostream>
- #include <tchar.h>
- #import <msxml3.dll>
- //节点处理函数
- void ProcessNode(MSXML2::IXMLDOMNodePtr spNode)
- {
- std::cout << "nodeName: " << spNode->nodeName;
- if (spNode->nodeType == NODE_ATTRIBUTE || spNode->nodeType == NODE_TEXT)
- std::cout << "\tnodeValue: " << _bstr_t(spNode->nodeValue);
- std::cout << std::endl;
- if (spNode->nodeType == NODE_ELEMENT)
- {
- MSXML2::IXMLDOMNamedNodeMapPtr spNameNodeMap = spNode->attributes;
- for (long i = 0; i != spNameNodeMap->length; ++i) //遍历节点属性
- ProcessNode(spNameNodeMap->item[i]);
- MSXML2::IXMLDOMNodeListPtr spNodeList = spNode->childNodes;
- for (long i = 0; i != spNodeList->length; ++i) //遍历子节点
- ProcessNode(spNodeList->item[i]);
- }
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- CoInitialize(NULL);
- //读取XML
- MSXML2::IXMLDOMDocumentPtr spXMLDoc;
- spXMLDoc.CreateInstance(__uuidof(MSXML2::DOMDocument30));
- spXMLDoc->load(L"stocks.xml");
- MSXML2::IXMLDOMElementPtr spRoot = spXMLDoc->documentElement; //根节点
- MSXML2::IXMLDOMNodeListPtr spNodeList = spRoot->childNodes;
- for (long i = 0; i != spNodeList->length; ++i) //遍历子节点
- ProcessNode(spNodeList->item[i]);
- //写入XML
- spRoot->selectSingleNode(L"/root/node1")->text = L"newText";
- spRoot->selectSingleNode(L"/root/node2/childnode1/@attrib1")->nodeValue = L"newValue";
- MSXML2::IXMLDOMNodePtr spNewNode = spRoot->selectSingleNode(L"/root/node2")->appendChild(
- spXMLDoc->createNode(_variant_t(NODE_ELEMENT), L"childnode3", L"")
- ); //给node2创建新子节点childnode3
- spNewNode->text = L"childtext2";
- MSXML2::IXMLDOMElementPtr spEle = spNewNode;
- spEle->setAttribute(L"attrib1", _variant_t(L"value1")); //添加新属性
- spXMLDoc->save(_variant_t(L"stocks.xml"));
- spNewNode.Release();
- spEle.Release();
- spNodeList.Release();
- spRoot.Release();
- spXMLDoc.Release();
- CoUninitialize();
- system("pause");
- return 0;
- }
VC++中操作XML(MFC、SDK)转的更多相关文章
- [转]VC++中操作XML(MFC、SDK)
XML在Win32程序方面应该没有在Web方面应用得多,很多Win32程序也只是用XML来存存配置信息而已,而且没有足够的好处的话还不如用ini.VC++里操作XML有两个库可以用:MSXML和Xml ...
- VC++中操作XMLWin32实例
摘要:VC++中操作XML XML在Win32程序方面应该没有在Web方面应用得多,很多Win32程序也只是用XML来存存配置信息而已,而且没有足够的好处的话还不如用ini.VC++里操作XML有两个 ...
- VBA中操作XML
OFFICE2007之后使用了OpenXml标准(伟大的改变),定制文本级的Ribbon可以通过修改压缩包内的xml文件来实现. 先学习一下VBA中操作XML的方法 先引用Microsoft XML ...
- 数据库中操作XML(openXML)
最近公司项目需要在数据库中操作XML,因此系统的学习了一下 一.openxml的格式 OPENXML( idoc int [ in] , XPathnvarchar [ in ] , [ flags ...
- C#.Net中操作XML方法一
我们知道XML是一种可标记性的语言,用来标记数据.定义数据类型,是一种执行用户对自己的标记语言进行定义的源语言.由于结构好.而且easy理解,就好比一棵树,层次关系分明,因此也经常把一些数据存储到XM ...
- C#中操作xml文件(插入节点、修改、删除)
已知有一个xml文件(bookstore.xml)如下: <?xml version="1.0" encoding="gb2312"?> <b ...
- 第12章 在.NET中操作XML
12.1 XML概述 12.1.1 为什么要有XML 12.1.2 XML文档结构 (1)文档声明 <?xml version="1.0"encoding="UTF ...
- Flex中操作XML的E4X方法
用于处理 XML 的 E4X 方法 Flash Player 9 和更高版本,Adobe AIR 1.0 和更高版本 ECMAScript for XML 规范定义了一组用于使用 XML 数据的类 ...
- VC,VB操作XML
TCHAR buffer[MAX_PATH] = {}; ::GetModuleFileName(NULL, buffer, MAX_PATH); CString strPath = buffer; ...
随机推荐
- node.js笔记
在node环境上面运行js代码,js相当于php,node相当于apache环境 第一步装 node 环境1.从官网下载 dmg 文件安装2.通过命令行安装 需要用到 homebrew(mac上专门用 ...
- Hive 实战(2)--hive分区分桶实战
前言: 互联网应用, 当Mysql单机遇到性能瓶颈时, 往往采用的优化策略是分库分表. 由于互联网应用普遍的弱事务性, 这种优化效果非常的显著.而Hive作为数据仓库, 当数据量达到一定数量时, 查询 ...
- 使用JavaScript设置、获取父子页面中的值
一:获取父页面中的值 有二种方法windows.open()和windows.showModalDialog() 1.windos.open(URL,name,reatures,replace) 再父 ...
- squid ACL 大全
Access Controls in Squid Contents Access Controls in Squid The Basics: How the parts fit together AC ...
- 关于 MAXScript 如何获取当前max版本
用到了 GetFileVersion 相关文档在此:http://docs.autodesk.com/3DSMAX/16/ENU/MAXScript-Help/index.html?url=files ...
- 黑马程序员——JAVA基础之正则表达式,网络爬虫
------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 正则表达式: 概念:用于操作字符串的符合一定规则的表达式 特点:用于一些特定的符号来表示一些代码 ...
- C#调用C++ DLL类方法
C++的优势在于高效灵活,C#的优势在于简单易用,两者结合起来对项目开发来说是件好事,而且C++不容易反编译,也保障了代码的安全性,如果一些核心算法使用C#编写,那么保密就是一个问题. C++生成的D ...
- Ubuntu14.04搭建Caffe(仅CPU)
一直以来都没有写博客的习惯,后来发现以前做的工作如果不注意及时整理和记录往往丢失的很快.对我而言这是一篇具有重要意义的文章,好的习惯要持之以恒,以后的日子我会常驻博客园!由于本人水平有限,智商略低,欢 ...
- SpringMVC学习系列(4) 之 数据绑定-1
在系列(3)中我们介绍了请求是如何映射到一个action上的,下一步当然是如何获取到请求中的数据,这就引出了本篇所要讲的内容—数据绑定. 首先看一下都有哪些绑定数据的注解: 1.@RequestPar ...
- 外联css及js的使用
结构图如下: html如下: <!DOCTYPE html> <html> <head> <title>button test</title> ...