当前位置: 首页 > backend >正文

使用MSXML2解析XML文件

最近在做项目的过程中,需要解析XML文件的内容。本篇文章记录一下自己使用MSXML2解析XML文件。

XML文件说明

  • 1.什么是XML?XML文件的存储格式是怎样的?
  • 2.什么是MSXML2?
  • 3.如何使用MSXML2解析XML文件?

1.什么是XML?XML文件的存储格式是怎样的?

1.XML文件的定义:
可扩展标记语言,标准通用标记语言的子集,简称XML,是一种用于标记电子文件使其具有结构性的标记语言。——摘自百度百科。大家可以参考什么是XML文件
2.XML文件的格式或者内容长什么样子呢

<?xml version="1.0" encoding="UTF-8"?>
<site><name>RUNOOB</name><url>https://www.runoob.com</url><logo>runoob-logo.png</logo><desc>编程学习网站</desc>
</site>

如上所述,第一行以XML开头,用来描述文档的一些信息。
,,, 都是标签,分别包含了要传递的信息。
标签必须成对出现,又开始标签就有结束标签。
XML文件形成了一种树结构,它从“根部“”开始,然后扩展到“枝叶”。
根元素:
开始标签:
结束标签:
接下来是描述根的子元素:




还有包含在子元素的中的文本分别是:
RUNOOB
https://www.runoob.com
runoob-logo.png
编程学习网站
下面看一张图更加的直观,有助于理解
在这里插入图片描述

<bookstore><book category="COOKING"><title lang="en">Everyday Italian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price></book><book category="CHILDREN"><title lang="en">Harry Potter</title><author>J K. Rowling</author><year>2005</year><price>29.99</price></book><book category="WEB"><title lang="en">Learning XML</title><author>Erik T. Ray</author><year>2003</year><price>39.95</price></book>
</bookstore>

实例中的根元素是 。文档中的所有 元素都被包含在 中。
元素有 4 个子元素:、、、。

关于XML文档更加详细的说明大家可以参考[菜鸟教程]中的说明。(https://www.runoob.com/xml/xml-tree.html)

2.什么是MSXML2?

百度百科上的说法是:msxml指微软的xml语言解析器,用来解释xml语言的。
MSXML的主要接口有哪些呢:
1.DOM Document
DOMDocument对象是XML DOM的基础,你可以利用它所暴露的属性和方法来允许你浏览、查询和修改XML文档的内容和结构。DOMDocument表示了树的顶层节点。它实现了DOM文档的所有的基本的方法并且提供了额外的成员函数来支持XSL和XSLT。它创建了一个文档对象,所有其他的对象都可以从这个文档对象中得到和创建。
2.IXML DOMNode
IXMLDOMNode是文档对象模型(DOM)中的基本的对象,元素,属性,注释,过程指令和其他的文档组件都可以认为是IXMLDOMNode,事实上,DOMDocument对象本身也是一个IXMLDOMNode对象。
3.IXML DOM NodeList
IXMLDOMNodeList实际上是一个节点(Node)对象的集合,节点的增加、删除和变化都可以在集合中立刻反映出来,可以通过“for…next”结构来遍历所有的节点。
4、IXMLDOMParseError
IXMLDOMParseError接口用来返回在解析过程中所出现的详细的信息,包括错误号,行号,字符位置和文本描述。

3.如何使用MSXML2解析XML文件?

MSXML2的使用方法大家可以参考MSXML2使用教程
下面我讲一下我使用MSXML2解析XML文件:
我用的是VS2022.
第一步:
在framework.h中添加如下语句:

#import"C:\\Windows\\System32\\msxml6.dll"
using namespace MSXML2;// 最好把这一段也加上
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif

大家如果找不到msxml6.dll的话,可以使用everything搜索即可。
由于我的项目是对话框项目,界面如下:
在这里插入图片描述
第二步:编写创建和读写XML文件的代码
1.我的项目名称叫做ReadWriteXML,创建XML文件的按钮代码如下:

void CReadWriteXMLDlg::OnBnClickedBtnCreate()
{// TODO: 在此添加控件通知处理程序代码// 创建一个文档指针MSXML2::IXMLDOMDocumentPtr pDoc;MSXML2::IXMLDOMElementPtr pRoot;// 实例化文档指针HRESULT hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument60));if (!SUCCEEDED(hr)){MessageBox(_T("XML文件创建失败!"));return;}pDoc->raw_createElement((_bstr_t)_T("China"),&pRoot);pDoc->raw_appendChild(pRoot,NULL);MSXML2::IXMLDOMElementPtr pElemNode;pDoc->raw_createElement((_bstr_t)_T("City"), &pElemNode);pElemNode->Puttext(_T("上海"));pElemNode->setAttribute(_T("Population"),_T("5000"));pElemNode->setAttribute(_T("Area"), _T("3000"));pRoot->appendChild(pElemNode);pDoc->raw_createElement((_bstr_t)_T("City"), &pElemNode);pElemNode->Puttext(_T("深圳"));pElemNode->setAttribute(_T("Population"), _T("2000"));pElemNode->setAttribute(_T("Area"), _T("1000"));pRoot->appendChild(pElemNode);pDoc->raw_createElement((_bstr_t)_T("City"), &pElemNode);pElemNode->Puttext(_T("北京"));pElemNode->setAttribute(_T("Population"), _T("8000"));pElemNode->setAttribute(_T("Area"), _T("6000"));pRoot->appendChild(pElemNode);pDoc->raw_createElement((_bstr_t)_T("City"), &pElemNode);pElemNode->Puttext(_T("广州"));pElemNode->setAttribute(_T("Population"), _T("9000"));pElemNode->setAttribute(_T("Area"), _T("7000"));pRoot->appendChild(pElemNode);pDoc->save(_T("..\\Bin\\MyTest.xml"));
}

创建的XML文件内容如下:

<China>
<City Population="5000" Area="3000">上海</City>
<City Population="2000" Area="1000">深圳</City>
<City Population="8000" Area="6000">北京</City>
<City Population="9000" Area="7000">广州</City>
</China>

2.读取XML文件的代码如下:

void CReadWriteXMLDlg::OnBnClickedBtnRead()
{// TODO: 在此添加控件通知处理程序代码// 先删除所有,再读取m_ListXMLInfo.DeleteAllItems();// 创建一个XML文档指针MSXML2::IXMLDOMDocumentPtr pDoc;// 实例化一个文档指针HRESULT hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument60));if (!SUCCEEDED(hr)){MessageBox(_T("加载XML文件错误!"));return;}// 加载XML文件VARIANT_BOOL Load = pDoc->load((_bstr_t)_T("..\\Bin\\MyTest.xml"));if (Load != -1){MessageBox(_T("加载XML文件错误!"));return;}// 声明一个元素指针MSXML2::IXMLDOMElementPtr pElemNode;// 获取元素的信息;selectSingleNode():如果查询到一个或者多个结点,则返回第一个结点。否则返回NULLpElemNode = (MSXML2::IXMLDOMElementPtr)(pDoc->selectSingleNode(_T("//China")));// 声明一个容器类型,该类型通常用于容纳属性MSXML2::IXMLDOMNamedNodeMapPtr pAttrs = NULL;// 声明一个结点链表指针,可以增加,或者删除结点MSXML2::IXMLDOMNodeListPtr pNodeList = NULL;// 声明结点指针MSXML2::IXMLDOMNodePtr pAttrItem = NULL;// 获取pNodeList指向的子节点pElemNode->get_childNodes(&pNodeList);long nCount, iCount;MSXML2::IXMLDOMElementPtr pCurNode;// 获取pNodeList中结点的个数pNodeList->get_length(&iCount);for (int i = 0; i < iCount; i++){// nextNode:获取当前节点和CObList链表很像pCurNode = pNodeList->nextNode();// getAttribute:获取当前结点的属性集CString strPopular = pCurNode->getAttribute(_T("Population"));CString strArea = pCurNode->getAttribute(_T("Area"));// Gettext:获取属性对应的文本;Puttext():设置文本CString strElemText = (_bstr_t)pCurNode->Gettext();// 将获取的属性值添加到CListCtrl控件中m_ListXMLInfo.InsertItem(i, strElemText);m_ListXMLInfo.SetItemText(i,1, strPopular);m_ListXMLInfo.SetItemText(i, 2, strArea);}
}

从XML文件中读取的内容如下:
在这里插入图片描述
3.添加结点的代码如下:

void CReadWriteXMLDlg::OnBnClickedBtnAddinfo()
{// TODO: 在此添加控件通知处理程序代码UpdateData(TRUE);MSXML2::IXMLDOMDocumentPtr pDoc;HRESULT hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument60));if (!SUCCEEDED(hr)){MessageBox(_T("加载XML文件错误!"));return;}VARIANT_BOOL Load = pDoc->load((_bstr_t)_T("..\\Bin\\MyTest.xml"));if (Load != -1){MessageBox(_T("加载XML文件错误!"));return;}MSXML2::IXMLDOMElementPtr pElemNode;pDoc->raw_createElement((_bstr_t)_T("City"), &pElemNode);pElemNode->Puttext((_bstr_t)m_strCity);CString strPeople, strArae;strPeople.Format(_T("%d"), m_nPeople);strArae.Format(_T("%d"), m_nArea);pElemNode->setAttribute(_T("Population"), (_bstr_t)strPeople);pElemNode->setAttribute(_T("Area"), (_bstr_t)strArae);MSXML2::IXMLDOMElementPtr pRoot;pRoot = (MSXML2::IXMLDOMElementPtr)(pDoc->selectSingleNode(_T("//China")));pRoot->appendChild(pElemNode);pDoc->save(_T("..\\Bin\\MyTest.xml"));m_ListXMLInfo.DeleteAllItems();OnBnClickedBtnRead();
}

添加结点的效果如下:
在这里插入图片描述
4.删除结点的代码如下:

void CReadWriteXMLDlg::OnBnClickedBtnDelete()
{// TODO: 在此添加控件通知处理程序代码MSXML2::IXMLDOMDocumentPtr pDoc;HRESULT hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument60));if (!SUCCEEDED(hr)){MessageBox(_T("加载XML文件错误!"));return;}VARIANT_BOOL Load = pDoc->load((_bstr_t)_T("..\\Bin\\MyTest.xml"));if (Load != -1){MessageBox(_T("加载XML文件错误!"));return;}MSXML2::IXMLDOMElementPtr pRoot;pRoot = (MSXML2::IXMLDOMElementPtr)(pDoc->selectSingleNode(_T("//China")));MSXML2::IXMLDOMNodeListPtr pNodeList;pNodeList = pRoot->selectNodes(_T("City"));MSXML2::IXMLDOMNodePtr pNode;pNode = pNodeList->Getitem(m_nIndex);MSXML2::IXMLDOMNodePtr pOldNode;pRoot->raw_removeChild(pNode,&pOldNode);pDoc->save(_T("..\\Bin\\MyTest.xml"));m_ListXMLInfo.DeleteAllItems();OnBnClickedBtnRead();
}

删除结点的效果如下:
在这里插入图片描述
小结:使用MSXML2解析XML文件,最主要是要弄清楚MSXML2::IXMLDOMDocumentPtr、MSXML2::IXMLDOMElementPtr、MSXML2::IXMLDOMNodeListPtr、
MSXML2::IXMLDOMNodePtr
这几个类之间的关系。这需要大家不断的调试,尝试。欢迎大家交流指正,谢谢大家。

关于项目的源码大家可以参考码云
文章参考:
全面解析XML
菜鸟教程

http://www.xdnf.cn/news/11619.html

相关文章:

  • 2024年PHP从基础到高级详细教程(完整版)_php高级教程(1),2024年最新GitHub标星1w的Golang架构师必备技能
  • 5个常见运维场景,用这几个Python脚本就够了!
  • Source Insight(以下简称SI)是世界上最好的编辑器
  • Google Talk突袭腾讯、MSN
  • MeeGo移动应用程序开发入门
  • 零知识玩转AVH(7)—— 门槛任务(2)所遇错误及解决(1)
  • HTML5移动端手机网站开发流程
  • 什么是等保三级?等保三级的认证流程有哪些?
  • 利用这些“大模型部署工具”轻松部署属于你自己的AIGC大模型吧!
  • 国内外自动驾驶OS盘点
  • python 米家_在S60 3rd Edition 上的Python for S60 简介
  • GBK ansi ascii
  • 信用评分之二--信用评分中的评分卡中的A卡、B卡和C卡
  • matlab中unique的作用,matlab中的unique函数详解
  • 思科模拟器Cisco Packet Tracer交换机的端口聚合配置
  • 热烈庆祝 中国x3d学习网:http://www.x3dcn.cn/正式开通
  • 必看!Python最新学习路线(2024最新版)
  • 移动端web开发
  • 【编程之美】一摞烙饼的排序
  • Mac新升级系统OS X El Capitan实用新功能快速指南
  • react-three/postprocessing库的中文对照总结
  • Android FactoryTest 流程
  • matlab 手指指尖检测,简单粗糙的指尖检测方法(FingerTips Detection) | 学步园
  • iphone开发论坛汇总:
  • 聊聊通用会员卡/通用打折卡
  • 十部值得一看的电影
  • CCProxy代理上网设置方法
  • 硬盘空间丢失的原因及预防方法(转)
  • 在美国,男 / 女卫生间(厕所)的正确称呼为什么?请用英语写出答案。
  • Oracle数据库的备份与恢复