最近使用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>