【程序】C++使用MSXML6.0的IXMLDOMDocument接口解析XML文档

原创 2018年04月17日 18:14:43

【C++程序】

#include <MsXml6.h>
#include <stdio.h>

#pragma comment(lib, "msxml6.lib")

/*
参考资料:
  (1) VARIANT结构体: https://msdn.microsoft.com/en-us/library/windows/desktop/dd373687(v=vs.85).aspx
      VARIANT用于表示一个弱类型的变量
  (2) BSTR字符串: https://msdn.microsoft.com/en-us/library/windows/desktop/ms221069(v=vs.85).aspx
      BSTR字符串是用于COM组件对象模型的字符串格式, 字符串以表示字符串长度的4字节整数开始, 然后跟上UTF-16编码的wchar_t字符串(包括\0结束标志)。BSTR类型的变量是一个指针, 指向字符串的第一个字符处
	  例如, 一段起始地址为1000的内存空间, 则1000~1003这四个字节存放字符串的长度, 1004开始才是字符串的真正内容, BSTR变量应指向1004而不是1000

	  wchar_t *用于保存UTF-16编码格式的字符串, printf用%ls输出(不能有中文, 否则会出错)
	  要输出含有中文的wchar_t *字符串, 请使用WriteConsoleW函数
	  char *可以用来保存任意编码格式的字符串, 但只有ANSI格式才能使用printf的%s正确显示出来
	  在简体中文版操作系统下, ANSI就是GBK编码

	  MultiByteToWideChar函数可以将char *字符串转换为wchar_t *字符串
	  WideCharToMultiByte函数可以将wchar_t *字符串转换为char *t字符串
	  SysAllocString函数可以将wchar_t *字符串转换为BSTR字符串
  (3) IXMLDOMDocument接口: https://msdn.microsoft.com/en-us/library/windows/desktop/dd892951(v=vs.85).aspx
  (4) 组件对象模型COM: 
      https://msdn.microsoft.com/en-us/library/windows/desktop/ff485848(v=vs.85).aspx
      https://msdn.microsoft.com/en-us/library/windows/desktop/ms680573(v=vs.85).aspx
  (5) Windows窗口程序: https://msdn.microsoft.com/en-us/library/windows/desktop/ff381409(v=vs.85).aspx
*/

// 显示元素节点的属性值 (元素节点是一种节点)
void display_attribute(IXMLDOMElement *elem, const wchar_t *name, bool intval = false)
{
	BSTR bstr; // 表示一个字符串
	int num;
	VARIANT variant; // 表示一个弱类型的变量

	bstr = SysAllocString(name); // 必须用SysAllocString函数把wchar_t *字符串转换成BSTR字符串
	elem->getAttribute(bstr, &variant);
	SysFreeString(bstr); // 使用完字符串后必须释放

	printf("[Attribute] name=%ls, value=%ls", name, variant.bstrVal); // BSTR和wchar_t *字符串都用%ls输出
	if (intval)
	{
		num = _wtoi(variant.bstrVal); // 转换为整形
		printf(", 2*value=%d", 2 * num);
	}
	printf("\n");

	SysFreeString(variant.bstrVal); // 保存在Variant中的BSTR也必须释放掉
}

// 显示节点名称
void display_nodename(IXMLDOMNode *node)
{
	BSTR bstr;
	node->get_nodeName(&bstr);
	printf("[Node] name=%ls\n", bstr); // 使用%ls打印BSTR字符串内容
	SysFreeString(bstr); // 使用完字符串后必须释放
}

// 显示节点中的文本内容 (方法一)
/*
void display_content(IXMLDOMNode *node)
{
	BSTR text;
	node->get_text(&text);
	printf("[Text] %ls\n", text);
	SysFreeString(text);
}
*/

// 显示节点中的文本内容 (方法二)
// 文本内容是文本节点, 是node节点下的子节点
void display_content(IXMLDOMNode *node)
{
	IXMLDOMNode *child;
	VARIANT value;
	node->get_firstChild(&child); // 获取文本节点
	child->get_nodeValue(&value); // 得到文本节点的内容
	printf("[Text] %ls\n", value.bstrVal);

	SysFreeString(value.bstrVal);
	child->Release();
}

// 获取节点中的XML文本内容
void display_inner_xml(IXMLDOMNode *node)
{
	BSTR bstr;
	node->get_xml(&bstr);
	printf("[InnerXML] %ls\n", bstr);
	SysFreeString(bstr);
}

void read_xml(IXMLDOMDocument *pDoc)
{
	// 根节点
	IXMLDOMElement *root;
	pDoc->get_documentElement(&root);
	display_nodename(root);
	display_attribute(root, L"id", true);
	display_inner_xml(root);
	printf("\n");

	// 根节点下的子节点
	IXMLDOMNodeList *list;
	long i, len;
	root->get_childNodes(&list);
	list->get_length(&len);
	for (i = 0; i < len; i++)
	{
		IXMLDOMNode *item;
		list->get_item(i, &item);
		display_nodename(item);
		display_content(item);

		// 只有元素节点才有属性节点, 所以获取属性前要进行类型转换, 把node变为element node
		IXMLDOMElement *elem;
		item->QueryInterface(&elem);
		display_attribute(elem, L"name");
		elem->Release();

		item->Release();
		printf("\n");
	}
	list->Release();

	root->Release();
}

// 打开XML文件
void open_xml(const wchar_t *name)
{
	HRESULT hr;
	IXMLDOMDocument *pDoc;
	hr = CoCreateInstance(CLSID_DOMDocument60, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDoc));
	if (SUCCEEDED(hr))
	{
		VARIANT filename;
		VARIANT_BOOL flag;

		filename.bstrVal = SysAllocString(name); // 将wchar_t *转换为BSTR
		filename.vt = VT_BSTR;
		pDoc->load(filename, &flag);
		SysFreeString(filename.bstrVal);
		if (flag == VARIANT_TRUE)
		{
			printf("Load succeeded!\n");
			read_xml(pDoc);
		}
		else
			printf("Load failed!\n");

		pDoc->Release();
	}
}

int main(void)
{
	CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); // 初始化COM组件对象模型

	open_xml(L"data.xml");

	CoUninitialize();
	return 0;
}

【XML文档】

文档的标签之间最好不要用回车换行和空格,否则很容易被误识别为文本节点。

<?xml version="1.0" encoding="utf-8"?><data id="105"><book name="haha">abcd</book><book name="hoho">efgh</book></data>

【程序运行结果】

Load succeeded!
[Node] name=data
[Attribute] name=id, value=105, 2*value=210
[InnerXML] <data id="105"><book name="haha">abcd</book><book name="hoho">efgh</b
ook></data>

[Node] name=book
[Text] abcd
[Attribute] name=name, value=haha

[Node] name=book
[Text] efgh
[Attribute] name=name, value=hoho

Press any key to continue . . .

版权声明:本文为博主原创文章,欢迎转载 https://blog.csdn.net/ZLK1214/article/details/79978704

TCP协议规范

传输控制协议(Transmission Control Protocol, TCP)TCP协议主为了在主机间实现高可靠性的包交换传输协议。本文将描述协议标准和实现的一些方法。因为计算机网络在现代社会中...
  • wxyxl
  • wxyxl
  • 2001-05-04 13:56:00
  • 6679

5、使用DOM解析XML文档

DOM:Document Object Model (文档对象模型) 1、DOM与SAX W3C制定了一套书写XML分析器的标准接口规范--DOM。除此之外,XML_DEV邮件列表中的成员根据应用...
  • kaoa000
  • kaoa000
  • 2013-02-27 10:41:54
  • 2821

IXMLDOMDocument使用

  • 2011年11月16日 16:12
  • 1KB
  • 下载

(五)使用DOM解析XML文档

DOM:Document Object Model (文档对象模型) 1、DOM与SAX W3C制定了一套书写XML分析器的标准接口规范--DOM。除此之外,XML_DEV邮件列表中的成员...
  • IT_LOSER
  • IT_LOSER
  • 2016-10-11 09:21:40
  • 272

VC++6.0利用 IXMLDOMDocumentPtr,IXMLDOMElementPtr生成XML文档

可以新建一个基于MFC对话框的应用程序,在头文件或者开头处加入#import msxml4.dll 然后在界面上加一个按钮,添加按钮事件处理 运用库函数来生成xml文档     ...
  • xt_chaoji
  • xt_chaoji
  • 2010-06-22 13:40:00
  • 3973

创建IXMLDOMDocument对象的三种方法

1)[方法1] 直接创建 IXMLDOMDocument? , 例(1)?? uses msxml; ?? var DOC:IXMLDOMDocument;?? doc := CoDOMDocumen...
  • lwjghhh
  • lwjghhh
  • 2004-10-23 09:31:00
  • 1737

动态创建TXMLDocument--使用IXMLDocument接口

var XML : TXMLDocument; DocIntf : IXMLDocument; begin XML := TXMLDocument.Create(nil); DocIn...
  • u010973206
  • u010973206
  • 2015-04-18 13:24:58
  • 916

Dom解析XMl文档

在DOM接口规范中,有四个基本的接口:Document,Node,NodeList以及NamedNodeMap。在这四个基本接口中,Document接口是对文档进行操作的入口,它是从Node接口继承过...
  • ling913
  • ling913
  • 2014-05-14 16:02:11
  • 929

有效的XML文档以及解析技术

有效的XML文档:有效的XML除了要满足XML规范外,还要满足相应DTD和Schema定义的元素规则。            有效的XML一定是格式良好的,但格式良好的XML不一定是有效的 ...
  • zhou814484002
  • zhou814484002
  • 2016-10-18 08:59:51
  • 620

Dom解析XML

DOM(Document Object Model):W3C组织推荐的处理XML的标准接口.  http://www.w3.org/DOM/DOMTR.html  DOM特点:首先将整...
  • u013516966
  • u013516966
  • 2015-01-29 02:41:07
  • 947
收藏助手
不良信息举报
您举报文章:【程序】C++使用MSXML6.0的IXMLDOMDocument接口解析XML文档
举报原因:
原因补充:

(最多只允许输入30个字)