天天看點

C++ DOM讀寫xml(msxml6)

最近使用C++ DOM增删XML上的一個節點,以前沒有寫過,寫的過程中也碰到一些問題,寫完後整理了一下。運作在windows上,我用vs2015編譯的。

參考了https://www.cnblogs.com/areliang/archive/2011/11/23/2260566.html

示例中,添加函數會建立如下的xml。

<?xml version="1.0" encoding="utf-8"?>
<Animals>
  <dog>hei bei</dog>
  <pig>pei qi</pig>
  <Cat>hua mao</Cat>
  <Cat name="jiafei" color="yellow">jia fei mao</Cat>
  <Cat name="jingzhang" color="black">hei mao jing zhang</Cat>
</Animals>
           
#include <iostream>
#include <atlbase.h>
#include <msxml6.h>
#include <Windows.h>

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

using namespace std;

void CreateXmlAndAddNode()
{
	CoInitialize(NULL);
	CComPtr<IXMLDOMDocument> spXmldoc;
	HRESULT hr = spXmldoc.CoCreateInstance(CLSID_DOMDocument60);
	if (SUCCEEDED(hr))
	{
		CComPtr<IXMLDOMProcessingInstruction> spDOMPI;
		hr = spXmldoc->createProcessingInstruction(L"xml", L"version='1.0' encoding='utf-8'", &spDOMPI); // 建立聲明

		if (hr == S_OK)
		{
			CComPtr<IXMLDOMNode> outNode;
			spXmldoc->appendChild(spDOMPI, &outNode);	//添加首行節點
			outNode.Detach();

			CComPtr<IXMLDOMElement> pDOMRoot;
			hr = spXmldoc->createElement(L"Animals", &pDOMRoot);
			spXmldoc->appendChild(pDOMRoot, &outNode);		//添加根節點
			outNode.Detach();

			if (hr == S_OK)
			{
				CComPtr<IXMLDOMText> textNode;
				spXmldoc->createTextNode(L"\n\t", &textNode);
				
				CComPtr<IXMLDOMElement> pDOMElement1;
				pDOMRoot->appendChild(textNode, NULL);
				textNode.Detach();
				spXmldoc->createElement(L"dog", &pDOMElement1);
				pDOMElement1->put_text(L"hei bei");
				pDOMRoot->appendChild(pDOMElement1, NULL);

				spXmldoc->createTextNode(L"\n\t", &textNode);
				pDOMRoot->appendChild(textNode, NULL);
				textNode.Detach();
				CComPtr<IXMLDOMElement> pDOMElement2;
				spXmldoc->createElement(L"pig", &pDOMElement2);
				pDOMElement2->put_text(L"pei qi");
				pDOMRoot->appendChild(pDOMElement2, NULL);
		

				spXmldoc->createTextNode(L"\n\t", &textNode);
				pDOMRoot->appendChild(textNode, NULL);
				textNode.Detach();
				CComPtr<IXMLDOMElement> pDOMElement3;
				spXmldoc->createElement(L"Cat", &pDOMElement3);
				pDOMElement3->put_text(L"hua mao");
				pDOMRoot->appendChild(pDOMElement3, NULL);
			
				spXmldoc->createTextNode(L"\n\t", &textNode);
				pDOMRoot->appendChild(textNode, NULL);
				textNode.Detach();
				CComPtr<IXMLDOMElement> pDOMElement4;
				spXmldoc->createElement(L"Cat", &pDOMElement4);
				pDOMElement4->put_text(L"jia fei mao");
				pDOMElement4->setAttribute(L"name", CComVariant("jiafei"));	//添加屬性
				pDOMElement4->setAttribute(L"color", CComVariant("yellow"));
				pDOMRoot->appendChild(pDOMElement4, NULL);
				
				spXmldoc->createTextNode(L"\n\t", &textNode);
				pDOMRoot->appendChild(textNode, NULL);
				textNode.Detach();
				CComPtr<IXMLDOMElement> pDOMElement5;
				spXmldoc->createElement(L"Cat", &pDOMElement5);
				pDOMElement5->put_text(L"hei mao jing zhang");
				pDOMElement5->setAttribute(L"name", CComVariant("jingzhang"));
				pDOMElement5->setAttribute(L"color", CComVariant("black"));
				pDOMRoot->appendChild(pDOMElement5, NULL);

				spXmldoc->createTextNode(L"\n", &textNode);
				pDOMRoot->appendChild(textNode, NULL);
				textNode.Detach();
			}
		}
		spXmldoc->save(CComVariant("cppDOM.xml"));
		spXmldoc.Detach();
	}
	CoUninitialize();
}
           

我的電腦裡沒有msxml4,我在system32下找到了msxml6.dll。試了一下也好用。需要引入這個庫并包括頭檔案msxml6.h。這裡要注意的是增加了一些空的textnode節點來換行,不加的話生成的xml内容隻有一行。

删除函數://删除<Cat name="jiafei" color="yellow">jia fei mao</Cat>

這裡第一次接觸xpath,用它來定位節點很友善。

void DeleteNode()
{
	CoInitialize(NULL);
	CComPtr<IXMLDOMDocument> spXmldoc;
	HRESULT hr = spXmldoc.CoCreateInstance(CLSID_DOMDocument60);
	if (SUCCEEDED(hr))
	{
		VARIANT_BOOL isSuccessful;
		spXmldoc->load(CComVariant("cppDOM.xml"), &isSuccessful);
		if (VARIANT_TRUE == isSuccessful)
		{
			CComPtr<IXMLDOMElement> spRoot = NULL;
			hr = spXmldoc->get_documentElement(&spRoot);
			if (hr == S_OK)
			{
				CComPtr<IXMLDOMNode> spNode;
				//通過xpath尋找節點
				hr = spRoot->selectSingleNode(L"/Animals/Cat[contains(@name, 'jiafei') and contains(@color, 'yellow')]", &spNode);
				
				if (hr == S_OK)
				{
					spRoot->removeChild(spNode, NULL);//删除節點
				}
			}
		}
	}
	spXmldoc->save(CComVariant("cppDOM.xml"));
	spXmldoc.Detach();
	CoUninitialize();
}
           

删除後的xml是。

<?xml version="1.0" encoding="utf-8"?>
<Animals>
	<dog>hei bei</dog>
	<pig>pei qi</pig>
	<Cat>hua mao</Cat>
	<Cat name="jingzhang" color="black">hei mao jing zhang</Cat>
</Animals>