markdown test2

#home {
    width: auto;
    margin: 0 80px 0 0;
}

mkdir test.
#include <msxml6.h>   // 含有 MSXML最新版
#include <atlbase.h>
#include "atlstr.h"  // 含有CString, CStringW和CW2A
#include <iostream>  // 包含wcout函数
#include <string>    // 包含 c_str()函数, wcout
#include "comutil.h" // 包含_bstr_t
using namespace std;

const wchar_t *src = L""
L"<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n"
L"<root desc=\"Great\">\r\n"
L"  <text>Hey</text>\r\n"
L"    <layouts>\r\n"
L"    <lay index=\"15\" bold=\"true\"/>\r\n"
L"    <layoff index=\"12\"/>\r\n"
L"    <layin index=\"17\"/>\r\n"
L"  </layouts>\r\n"
L"</root>\r\n";

int main()
{
	CoInitialize(NULL); // Initialize COM

	CComPtr<IXMLDOMDocument> iXMLDoc;  // Or use CComPtr<IXMLDOMDocument2>, CComPtr<IXMLDOMDocument3>

	try
	{
		HRESULT hr = iXMLDoc.CoCreateInstance(__uuidof(DOMDocument));
		// 	iXMLDoc.CoCreateInstance(__uuidof(DOMDocument60));

		// Load the file. 
		VARIANT_BOOL bSuccess = false;

		// Load it from a url/filename...
		hr = iXMLDoc->load(CComVariant(L"./test.xml"), &bSuccess);
		// filePath = "./test.xml";
		// hr = iXMLDoc->load(CComVariant(filePath.c_str()), &bSuccess);

		// or from a BSTR...
		// iXMLDoc->loadXML(CComBSTR(src), &bSuccess);

		// Get a smart pointer (sp) to the root
		CComPtr<IXMLDOMElement> pRootElement;
		hr = iXMLDoc->get_documentElement(&pRootElement); // Root elements

		// Get Attribute value of the note "root"
		CComBSTR ssDesc("desc");
		CComVariant deVal(VT_EMPTY);
		hr = pRootElement->getAttribute(ssDesc, &deVal);

		CComBSTR sstrRoot(L"root"); // sstrRoot("root");
		CComPtr<IXMLDOMNode> rootNode;
		hr = iXMLDoc->selectSingleNode(sstrRoot, &rootNode);  // Search "root"

		CComBSTR rootText;
		hr = rootNode->get_text(&rootText);
		if (SUCCEEDED(hr))
		{
			wstring bstrText(rootText);
			wcout << "Text of root: " << bstrText << endl;
		}

		CComPtr<IXMLDOMNode> descAttribute;
		hr = rootNode->selectSingleNode(CComBSTR("@desc"), &descAttribute); // Atrribute需要用@, 而各个节点不能使用@作为前缀来搜索
		CComBSTR descVal;
		hr = descAttribute->get_text(&descVal);
		if (SUCCEEDED(hr))
		{
			wstring bstrText(descVal);
			wcout << "Desc Attribute: " << bstrText << endl;
		}

		if (!FAILED(hr))
		{
			wstring strVal;
			if (deVal.vt == VT_BSTR)
				strVal = deVal.bstrVal;

			wcout << "desc: " << strVal << endl;
		}

		CComPtr<IXMLDOMNodeList> pNodeList;
		pRootElement->get_childNodes(&pNodeList); // Child node list
		long nLen;
		pNodeList->get_length(&nLen);    // Child node list
		for (long i = 0; i != nLen; ++i) // Traverse
		{
			CComPtr<IXMLDOMNode> pNode;
			hr = pNodeList->get_item(i, &pNode);

			CComBSTR ssName;
			CComVariant val(VT_EMPTY);
			hr = pNode->get_nodeName(&ssName);
			if (SUCCEEDED(hr))
			{
				wstring bstrText(ssName);
				wcout << "Name of node " << (i + 1) << ": " << bstrText << endl;

				CString cstring(ssName);
				// To display a CStringW correctly, use wcout and cast cstring to (LPCTSTR), an easier way to display wide character strings.
				wcout << (LPCTSTR)cstring << endl;

				// CW2A converts the string in ccombstr to a multi-byte string in printstr, used for display output.
				CW2A printstr(ssName);
				cout << printstr << endl;
			}
		}

		// Add(Append) node
		CComPtr<IXMLDOMDocument>& xmlDocData(iXMLDoc);
		CComPtr<IXMLDOMElement> imageElement;
		CComPtr<IXMLDOMNode> newImageNode;
		string imageType = "jpeg";
		char buffer[MAX_PATH];
		GetCurrentDirectory(MAX_PATH, buffer);  //  Get Current Directory
		string path(buffer); // Copy content of char*, generate a string
		string imagePath = path + "\\com.jpg";

		xmlDocData->createElement(CComBSTR(L"Image"), &imageElement);
		imageElement->setAttribute(CComBSTR(L"Type"), CComVariant(CComBSTR(imageType.c_str()))); // 为当前节点添加属性
		imageElement->setAttribute(CComBSTR(L"FileName"), CComVariant(CComBSTR(imagePath.c_str())));
		rootNode->appendChild(imageElement, &newImageNode);

		// Remove "text" node under "root" node
		CComPtr<IXMLDOMNode> xmlOldNode;
		CComPtr<IXMLDOMNode> textNode;
		hr = rootNode->selectSingleNode(CComBSTR(L"text"), &textNode); // Search "text" node		
		hr = rootNode->removeChild(textNode, &xmlOldNode);

		// Update XML
		hr = iXMLDoc->save(CComVariant("updated.xml"));
	}
	catch (char* pStrErr) {
		// Some error...
		std::cout << pStrErr << std::endl << std::endl;
	} // catch
	catch (...) {
		// Unknown error...
		std::cout << "Unknown error..." << std::endl << std::endl;
	}

	// Release() - that gets done automatically, also can manually do for each opened node or elements.
	// iXMLDoc.Release();

	// Stop COM
	CoUninitialize();

	system("pause");
	return 0;
}

运行结果:
run Result

运行完,得到的update.xml内容为:
https://raw.githubusercontent.com/yanglr/SimpleParser4MSXML-cpp/master/msxmlDemo/updated.xml


参考资料:

  1. IXMLDOMElement接口
  2. Using the MSXML Parser
  3. MFC C++ XML Parse - Using MSXML
  4. 如何:各种字符串类型之间转换 | Microsoft Docs

bottom

cc

posted @ 2019-02-12 22:50  legege007  阅读(155)  评论(0编辑  收藏  举报
分享到: