MSXML 是 Microsoft 提供的高效能 XML DOM 解析器,透過 COM 介面操作 XML 文件樹。本文以主控台應用程式為例,示範載入 XML、XPath 查詢節點、建立子節點與屬性、提取文字內容、儲存修改後文件的完整流程,採用 ATL 智慧指標簡化 COM 資源管理。
xmldata.xml
<?xml version="1.0"?>
<xmldata>
<xmlnode />
<xmltext>Hello, World!</xmltext>
</xmldata>
::CoInitialize(NULL);
CComPtr<IXMLDOMDocument> spXMLDOM;
HRESULT hr = spXMLDOM.CoCreateInstance(__uuidof(DOMDocument));
if (FAILED(hr) || !spXMLDOM) throw "Unable to create XML parser";
VARIANT_BOOL bSuccess = FALSE;
hr = spXMLDOM->load(CComVariant(L"xmldata.xml"), &bSuccess);
if (FAILED(hr) || !bSuccess) throw "Unable to load XML document";
xmlnode
CComPtr<IXMLDOMNode> spXMLNode;
hr = spXMLDOM->selectSingleNode(CComBSTR(L"xmldata/xmlnode"), &spXMLNode);
if (FAILED(hr) || !spXMLNode) throw "Unable to locate 'xmlnode'";
xmlchildnode 並附加屬性 xml="fun"
CComPtr<IXMLDOMNode> spChildNode;
hr = spXMLDOM->createNode(CComVariant(NODE_ELEMENT), CComBSTR(L"xmlchildnode"), NULL, &spChildNode);
if (FAILED(hr) || !spChildNode) throw "Unable to create child node";
CComPtr<IXMLDOMNode> spInserted;
hr = spXMLNode->appendChild(spChildNode, &spInserted);
// 切換至 IXMLDOMElement 設定屬性
CComQIPtr<IXMLDOMElement> spElement = spInserted;
if (!spElement) throw "Query IXMLDOMElement failed";
hr = spElement->setAttribute(CComBSTR(L"xml"), CComVariant(L"fun"));
xmltext 並提取文字內容
CComPtr<IXMLDOMNode> spTextNode;
hr = spXMLDOM->selectSingleNode(CComBSTR(L"xmldata/xmltext"), &spTextNode);
CComVariant varValue;
hr = spTextNode->get_nodeTypedValue(&varValue);
if (SUCCEEDED(hr) && varValue.vt == VT_BSTR) {
USES_CONVERSION;
cout << W2T(varValue.bstrVal) << endl; // 輸出 Hello, World!
}
hr = spXMLDOM->save(CComVariant(L"updatedxml.xml"));
if (FAILED(hr)) throw "Unable to save updated XML";
updatedxml.xml
<?xml version="1.0"?>
<xmldata>
<xmlnode>
<xmlchildnode xml="fun" />
</xmlnode>
<xmltext>Hello, World!</xmltext>
</xmldata>
| DOM 介面 | MSXML COM 介面 | 主要用途 |
|---|---|---|
| Document | IXMLDOMDocument | 載入、儲存、XPath 查詢、建立節點 |
| Node | IXMLDOMNode | 樹狀導航、appendChild、get_nodeTypedValue |
| Element | IXMLDOMElement | setAttribute、getAttribute |
| NodeList | IXMLDOMNodeList | 批次迭代節點集合 |
SAX(ISAXXMLReader)流式解析,避免完整 DOM 樹佔用過多記憶體。SelectionNamespaces 屬性註冊前綴。IXMLDOMParseError 提供詳細行號、錯誌代碼與原因描述。MSXML 功能強大且成熟,搭配 ATL 智慧指標可編寫健壯、無記憶體洩漏的 XML 處理代碼。