msxml

// MsXmlDemo.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <atlbase.h>
#include <atlstr.h>
#include <iostream>
using namespace std;

#import "msxml6.dll"

class CIndentHelper
{
public:
	CIndentHelper()
	{
		ms_depth++;
	}

	~CIndentHelper()
	{
		ms_depth--;
	}
private:
	static int ms_depth;
	static string ms_indent;

public:
	static LPCSTR ToString()
	{
		ms_indent="";
		for (int i=0;i<ms_depth;i++)
		{
			ms_indent+="\t";
		}

		return ms_indent.c_str();
	}
};

int CIndentHelper::ms_depth=-1;
string CIndentHelper::ms_indent="";
/*

<?xml version="1.0" encoding="UTF-8" ?> 
<package xmlns="http://www.topsec.com.cn" version="2.0" unique-identifier="301127">
	<metadata xmlns:ops="http://www.idpf.org/2007/opf" xmlns:dc="http://purl.org/dc/elements/1.1/">
		<dc:identifier ops:scheme="9787802102194" /> 
	</metadata>
	<manifest>
		
		<item class="pre" href="cover.jpg" /> 
		<item class="body" href="first.xml" /> 
		<item class="body" href="second.xml" /> 
	</manifest>
</package>

*/

void SetElementAttribute(MSXML2::IXMLDOMElementPtr spelment, _bstr_t name, _variant_t var)
{
	MSXML2::IXMLDOMDocumentPtr spDocument=spelment->GetownerDocument();
	MSXML2::IXMLDOMAttributePtr spAttribtue = spDocument->createAttribute(name);
	spAttribtue->put_nodeValue(var);
	spelment->setAttributeNode(spAttribtue);
}

void AddManifestItem(MSXML2::IXMLDOMElementPtr spManifest, _bstr_t bstrCls, _bstr_t bstrhref)
{
	MSXML2::IXMLDOMDocumentPtr spDocument=spManifest->GetownerDocument();
	_bstr_t ns = spManifest->GetnamespaceURI();
	MSXML2::IXMLDOMNodePtr spItemNode = spDocument->createNode(_variant_t(NODE_ELEMENT), _bstr_t("item"), ns);
	MSXML2::IXMLDOMElementPtr spItem = spItemNode;
	spItem->setAttribute(_bstr_t("class"), _variant_t(bstrCls));
	spItem->setAttribute(_bstr_t("href"), _variant_t(bstrhref));
	spManifest->appendChild(spItem);
}

void CreateXml()
{
	MSXML2::IXMLDOMDocumentPtr spDocument;
	HRESULT hr;

	_bstr_t TsNsUrl("http://www.topsec.com.cn");
	_bstr_t TdNsUrl("http://www.topdesk.com.cn");
	_bstr_t TaNsUrl("http://www.topagent.com.cn");
	_bstr_t OpfNsUrl("http://www.idpf.org/2007/opf");
	_bstr_t DcNsUrl("http://purl.org/dc/elements/1.1/");

	USES_CONVERSION;

	try
	{
		CoInitializeEx(NULL,COINIT_MULTITHREADED);
		hr = spDocument.CreateInstance(__uuidof(MSXML2::DOMDocument60));

		//创建预处理指令
		MSXML2::IXMLDOMProcessingInstructionPtr spDomPI=spDocument->createProcessingInstruction(_bstr_t("xml"),_bstr_t("version=\"1.0\" encoding=\"UTF-8\""));
		spDocument->appendChild(spDomPI);
		
		MSXML2::IXMLDOMNodePtr spRootNode = spDocument->createNode(_variant_t(NODE_ELEMENT), _bstr_t("package"),TsNsUrl);
		SetElementAttribute(spRootNode, _bstr_t("version"), _variant_t("2.0"));
		SetElementAttribute(spRootNode, _bstr_t("unique-identifier"), _variant_t("301127"));
		spDocument->appendChild(spRootNode);

		MSXML2::IXMLDOMNodePtr spMetadata = spDocument->createNode(_variant_t(NODE_ELEMENT), _bstr_t("metadata"), TsNsUrl);
		SetElementAttribute(spMetadata, _bstr_t("xmlns:ops"), _variant_t(OpfNsUrl));
		SetElementAttribute(spMetadata, _bstr_t("xmlns:dc"), _variant_t(DcNsUrl));
		spRootNode->appendChild(spMetadata);

		MSXML2::IXMLDOMNodePtr spCreator = spDocument->createNode(_variant_t(NODE_ELEMENT), _bstr_t("dc:creator"), DcNsUrl);
		spCreator->put_text(_bstr_t("小布兜"));
		spMetadata->appendChild(spCreator);

		MSXML2::IXMLDOMNodePtr spIdentifier = spDocument->createNode(_variant_t(NODE_ELEMENT), _bstr_t("dc:identifier"), DcNsUrl);
		SetElementAttribute(spIdentifier, _bstr_t("ops:scheme"), _variant_t("9787802102194"));
		spMetadata->appendChild(spIdentifier);

		MSXML2::IXMLDOMNodePtr spManifest = spDocument->createNode(_variant_t(NODE_ELEMENT), _bstr_t("manifest"), TsNsUrl);

		MSXML2::IXMLDOMCommentPtr spComment = spDocument->createComment(_bstr_t("the following is item list"));
		spManifest->appendChild(spComment);

		MSXML2::IXMLDOMCDATASectionPtr spCDataSection = spDocument->createCDATASection(_bstr_t("this is a CDATA section"));
		spManifest->appendChild(spCDataSection);

		AddManifestItem(spManifest,_bstr_t("pre"), _bstr_t("cover.jpg"));
		AddManifestItem(spManifest,_bstr_t("body"), _bstr_t("first.xml"));
		AddManifestItem(spManifest,_bstr_t("body"), _bstr_t("second.xml"));
		spRootNode->appendChild(spManifest);


		spDocument->save(_variant_t("test.xml"));
	}
	catch (_com_error& err)
	{
		_bstr_t bstrMessage(err.ErrorMessage());
		cout<<(LPCSTR)bstrMessage<<endl;
	}
}


CString GetExecutablePath()
{
	TCHAR buffer[MAX_PATH];
	GetModuleFileName(NULL,buffer,MAX_PATH);
	CString strPaht=buffer;
	int index=strPaht.ReverseFind(_T('\\'));
	strPaht=strPaht.Left(index);
	return strPaht;
}


void ExtractDomNodeInfo(MSXML2::IXMLDOMNodePtr spNode)
{
	USES_CONVERSION;
	CIndentHelper helper;

	MSXML2::DOMNodeType nodeType;
	spNode->get_nodeType(&nodeType);
	BSTR bstrText;
	spNode->get_text(&bstrText);
	
	switch(nodeType)
	{
	case NODE_TEXT:
		{
			cout<<CIndentHelper::ToString()<<"NODE_TEXT: "<<W2A(bstrText)<<endl;
		}
		break;
	case NODE_PROCESSING_INSTRUCTION:
		{
			cout<<CIndentHelper::ToString()<<"NODE_PROCESSING_INSTRUCTION: <?"<<W2A(bstrText)<<"?>"<<endl;
		}
		break;
	case NODE_COMMENT:
		{
			cout<<CIndentHelper::ToString()<<"NODE_COMMENT: <!--"<<W2A(bstrText)<<"-->"<<endl;
		}
		break;
	case NODE_CDATA_SECTION:
		{
			cout<<CIndentHelper::ToString()<<"NODE_CDATA_SECTION: <![CDATA["<<W2A(bstrText)<<"]]>"<<endl;
		}
		break;
	case NODE_ELEMENT:
		{
			IXMLDOMNamedNodeMapPtr spNamedNodemap;
			IXMLDOMElementPtr spItem = spNode;
			BSTR bstrTagName;
			spItem->get_tagName(&bstrTagName);
			cout<<CIndentHelper::ToString()<<"NODE_ELEMENT: "<<W2A(bstrTagName)<<endl;

			//enumerate attributes
			spItem->get_attributes(&spNamedNodemap);
			long attrlen;
			spNamedNodemap->get_length(&attrlen);
			for (int i=0;i<attrlen;i++)
			{
				IXMLDOMNodePtr spattri;
				spNamedNodemap->get_item(i, &spattri);
				BSTR bstrName;
				BSTR bstrValue;
				spattri->get_nodeName(&bstrName);
				spattri->get_text(&bstrValue);
				cout<<CIndentHelper::ToString()<<"\t"<<W2A(bstrName)<<"=\""<<W2A(bstrValue)<<"\""<<endl;
			}
		}
		break;
	}

	MSXML2::IXMLDOMNodeListPtr spNodeList;
	if(spNode->get_childNodes(&spNodeList)==S_OK)
	{
		long count;
		spNodeList->get_length(&count);
		for (int i=0;i<count;i++)
		{
			MSXML2::IXMLDOMNodePtr spSubNode=spNodeList->Getitem(i);
			ExtractDomNodeInfo(spSubNode);
		}
	}

	::SysFreeString(bstrText);
}

void ReadXml()
{
	MSXML2::IXMLDOMDocumentPtr spDocument;
	HRESULT hr;

	USES_CONVERSION;

	try
	{
		CoInitializeEx(NULL,COINIT_MULTITHREADED);
		hr = spDocument.CreateInstance(__uuidof(MSXML2::DOMDocument60));
		VARIANT_BOOL bLoadOK = spDocument->load(_variant_t("test.xml"));
		if (bLoadOK==VARIANT_FALSE)
		{
			cout<<"load xml file failed."<<endl;
		}

		MSXML2::IXMLDOMNodeListPtr spNodeList;
		hr = spDocument->get_childNodes(&spNodeList);
		long count;
		spNodeList->get_length(&count);

		for (int i=0;i<count;i++)
		{
			MSXML2::IXMLDOMNodePtr spNode=spNodeList->Getitem(i);
			ExtractDomNodeInfo(spNode);
		}
	}
	catch (_com_error& err)
	{
		_bstr_t bstrMessage(err.ErrorMessage());
		cout<<(LPCSTR)bstrMessage<<endl;
	}
}

void ReadXmlWithXPath()
{
	/************************************************************************/
	/* because setProperty exist in IXMLDOMDocument2 interface*/
	/************************************************************************/
	MSXML2::IXMLDOMDocument2Ptr spDocument;
	HRESULT hr;

	USES_CONVERSION;

	try
	{
		CoInitializeEx(NULL,COINIT_MULTITHREADED);
		hr = spDocument.CreateInstance(__uuidof(MSXML2::DOMDocument));
		VARIANT_BOOL bLoadOK = spDocument->load(_variant_t("test.xml"));
		if (bLoadOK==VARIANT_FALSE)
		{
			cout<<"load xml file failed."<<endl;
		}

		MSXML2::IXMLDOMElementPtr spRootele = spDocument->GetdocumentElement();
		BSTR tagName;
		spRootele->get_tagName(&tagName);
		cout<<"Root element : "<<W2A(tagName)<<endl;
		::SysFreeString(tagName);

		/*
		SelectionLanguage Property
		Used in MSXML 3.0 to specify whether the DOM object should use XPath language ("XPath") or 
		the old XSLPattern language (default) as the query language. 
		This property is supported in MSXML 3.0 6.0. The default value is "XSLPattern" for 3.0. 
		The default value is "XPath" for 6.0.
		*/
		//The following expression will throw a exception, because msxml6 remove the XSLPattern support.
		//spDocument->setProperty(_bstr_t("SelectionLanguage"),_variant_t("XSLPattern"));

		/*
		SelectionNamespaces Property
		Specifies namespaces for use in XPath expressions when it is necessary to define
		new namespaces externally. Namespaces are defined in the XML style, 
		as a space-separated list of namespace declaration attributes. 
		You can use this property to set the default namespace as well.
		This property is supported in MSXML 3.0 and 6.0. The default value is "".
		When an XML document contains elements defined in an external namespace, 
		you must use this property to specify that namespace in order to use DOM methods 
		such as selectNodes or selectSingleNode to navigate the document. 
		*/

		/*若使用XSLPattern查询语言,则不需要设置SelectionNamespaces属性,若使用XPath语言,并且所查询节点存在于某命名空间内,则
		必须设置SelectionNamespaces,并且默认的命名空间必须有别名*/
		_bstr_t bstrNS("xmlns:default='http://www.topsec.com.cn' xmlns:dc='http://purl.org/dc/elements/1.1/'");
		hr = spDocument->setProperty(_bstr_t("SelectionNamespaces"),_variant_t(bstrNS));
		MSXML2::IXMLDOMElementPtr spManifest = spRootele->selectSingleNode(_bstr_t("default:metadata/dc:creator"));

		if(spManifest==nullptr)
		{
			cout<<"query manifest failed."<<endl;
		}
		else
		{
			spManifest->get_tagName(&tagName);
			cout<<"Query element : "<<W2A(tagName)<<endl;
			::SysFreeString(tagName);
		}
	}
	catch (_com_error& err)
	{
		_bstr_t bstrMessage(err.Description());
		cout<<(LPCSTR)bstrMessage<<endl;
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	//设置当前目录
	SetCurrentDirectory(GetExecutablePath());
	CreateXml();
	ReadXml();
	ReadXmlWithXPath();
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值