最近研究起了使用VC6.0进行解析XML文档,而对于XML文档的解析目前网上主要使用了两种方法:MSXML和CMarkUp类。而我就先从最基本的DOM研究起了。而对于DOM主要采用微软提供的MSXML库,另外好像还有第三方库TinyXML,咱就不研究了。
而对于MSXML的使用,网上别人提供的东西都比较零碎,而且还比较乱,在论坛上问反而被一堆人鄙视,得到的解答少之又少。于是我专门花了一天的时间研究了下,现在小有成果,就感觉整理了一些,以供和我一样初级选手作为入门的资料。当然,在整理过程中还是会出现错误,望大家发现后指正。如果你感觉文章还好的话就留个足迹,顶顶人气哈。
闲话到此为止,下面进入正题:
1. 开发环境
系统中须保证已经安装了msxml。以下均针对msxml4版本进行的操作,而对msxml6的版本则需要进行相应的改动即可。
编程开发环境Visual C++ 6.0。
2. 具体开发实现
2.1 导入库
在使用msxml之前,第一步要做的就是导入该库。导入msxml4库需要进行以下操作:
#include "msxml.h"
#import "C:/windows/system32/msxml.dll" rename_namespace("xml")
即:首先要包含头文件,然后在导入库,并重新定义了一个命名空间,这样为了以后使用的方面。
2.2 初始化com库
因为该库为COM组件,故使用前需要初始化com组件库。
AfxOleInit(); 或是 ::CoInitialize(NULL); // 初始化Com组件。
同时,若不再使用该MSXML组件时,可以释放组件占用的内存。
::CoUninitialize();
以上两步做完之后就可以使用DOM库了。
2.3 文档类:IXMLDOMDocumentPtr
Document节点代表了整个的XML文档。当DOM解析一个XML文档后,由XML形成的DOM节点树以Document对象的形式展现给应用程序的。由于XMl文档的元素、处理指令、注释等都处于一个XML文档范围之内,Document中包含了用于创建元素、属性、注释、处理指令等其它节点类型的方法。
因此,首先要创建XML文档类对象
xml::IXMLDOMDocumentPtr pDoc;
// 创建DOC类,注意是 ' . ',而不是 ' -> ',尽管它是一个指针。
HRESULT hr = pDoc.CreateInstance(_uuidof(xml::DOMDocument));
if(!SUCCEEDED(hr))
{
AfxMessageBox("无法创建DM对象!");
return;
}
创建完成了Document文档类对象之后就可以进行下一步的创建XML或是解析操作了。
以下介绍一些常用的方法:
1) 创建元素:XMLDOMDocument->createElement(name);
2) 创建节点:XMLDOMDocument->createNode(name);
3) 添加节点:XMLDOMDocument->appendChild();
4) 保存生成XML文档:XMLDOMDocument->save();
5) 加载XML文档:XMLDOMDocument->load("path.xml");
6) 获取根节点:XMLDOMDocument->get_documentElement(&root)
以上几个方法基本上就可以创建和解析一个简单的XML文档了。
2.4 节点类:IXMLDOMNode
DOM是由一组抽象化的接口组成。Node是整个DOM中最基本的数据类型,它代表了一个抽象的节点。XML文档的DOM树上的具体节点类型都是由Node类型派生而来。
其提供的常用属性或方法如下:
(1)子节点操作
-
- childNodes:子节点列表。
- get_childNodes ():获取子节点列表。
- appendChild():添加子节点。
- hasChildNodes():判断是否含有子节点。若有返回true。
- insertBefore():插入子节点。
- removeChild():删除子节点。
- replaceChild():替换子节点。
(2)查询节点
selectNodes():
运用专门的模式匹配方法匹配要查询的节点,并返回满足要求的节点列表。
selectSingleNode()
运用专门的模式匹配方法匹配要查询的节点,并返回满足要求的第一个节点。
(3)节点名
nodeName:属性,指示了节点的名称。
get_nodeName():返回节点名称。
(4)节点类型
nodeType:属性,指示了节点的类型。
节点类型有:NODE_ELEMENT、NODE_ATTRIBUTE、NODE_TEXT、 NODE_ENTITY、NODE_PROCESSING_INSTRUCTION、 NODE_DOCUMENT、NODE_DOCUMENT_TYPE等。
Get_nodeType():返回该节点的类型。
(5)节点值
-
- nodeValue:代表了节点的text值。
- put_nodeValue():设置节点值。
- get_nodeValue():获取节点值。
(6)节点文本值
-
- text:代表节点和其子树的text值。
- put_text():设置text。
- get_text():获取text。
(7)节点属性
-
- attributes:包含了节点的属性列表。
- get_attributes():获取节点属性列表。
其中更详细信息请参考MSDN。
2.5 XML文档序Prolog类:IXMLDOMProcessingInstructionPtr
文档序需要由Document类创建,如:
xml::IXMLDOMProcessingInstructionPtr head;
head = pDoc->createProcessingInstruction(_bstr_t(_T("xml")),
_bstr_t(_T("version='1.0' encoding='UTF-8'")));
pDoc->appendChild(head); // 将序添加到文档类中。
2.6 元素类:IXMLDOMElementPtr
该节点继承自IXMLDOMNode。其具体属性和方法同IXMLDOMNodePtr,不再细述。
2.7 命名的节点表IXMLDOMNamedNodeMap
通过属性节点集合实现对命名空间和迭代的支持。IXMLDOMNamedNodeMap为一个节点集,并且支持通过名称或标签值的访问。该集合主要应用于对属性的支持。
如若想解析一个元素的属性,可用以下操作实现:
IXMLDOMNamedNodeMapPtr pAttrMap = NULL;
IXMLDOMElementPtr:proot->get_attributes(&pAttrMap);
long count;
BSTR content, name;
pAttrMap->get_length(&count);
pAttrMap->get_item(0, &pAttrItem);
pAttrItem->get_text(&content);
pAttrItem->get_nodeName(&name);
该类所提供的属性和方法有:
-
- length:该集合中的属性个数。
- get_length():获取length。
- getNamedItem():检索指定名称的属性。
- getQualifiedItem():返回指定名称空间和属性名称的属性。
其它见优快云技术文档。
2.8 属性类:IXMLDOMAttribute
指示了元素IXMLDOMElement的一个属性。属性继承于IXMLDOMNode类,但不不属于元素的一个子节点,同样也不属于文档树的一个节点。
其具体属性和方法也不做详细介绍,具体可参考优快云技术文档。
2.9 释放元素
在使用完节点(IXMLDOMNode,包括其子类)之后,需要释放其所占用的资源,否则会造成消耗大量系统内存资源。释放使用如下操作:
Node->Release();
Doc->Release();
3. 具体实例
3.1 创建XML文档
如此得到的XML文档为:
<?xml version="1.0" encoding="UTF-8"?>
<People id="001">
<Name>零零喜</Name>
<Profession>大内密探</Profession>
</People>
实际中,可能会出现排版问题。比如元素及子元素均放在一行中,这也是我咱是还没解决的。
3.2 解析XML文档
其中实例如下: