写本文的目的是为了方便大家了解C++ MSXML操作方法。
当然,C++中对MSXML的调用有多种,本文采用的方法是完全参照MSXML SDK提供的文档进行操作。
如果有什么错误,欢迎指正。
代码框架是基于vs2008 MFC 对话框程序(UNICODE)。对话框程序需要读者自己创建。
- #include <msxml6.h>
- #include <comutil.h>
- #pragma comment(lib, "comsuppwd.lib")
- void CXmlSampleDlg::OnBnClickedButton1()//按钮事件
- {
- CoInitialize(NULL);
- CComPtr<IXMLDOMDocument> spXmldoc;
- HRESULT hr = spXmldoc.CoCreateInstance(L"MSXML2.DOMDocument.6.0");
- if(SUCCEEDED(hr))
- {
- VARIANT_BOOL isSuccessFul;
- CComVariant varXmlFile(L"a.xml");
- spXmldoc->put_async(VARIANT_FALSE);
- HRESULT hr= spXmldoc->load(varXmlFile, &isSuccessFul);
- if(isSuccessFul==VARIANT_TRUE)
- {
- CComBSTR bstrXml;
- CComPtr<IXMLDOMElement> spRoot=NULL;
- CComPtr<IXMLDOMElement> spTheBook=NULL;
- CComPtr<IXMLDOMElement> spTheElem=NULL;
- CComPtr<IXMLDOMNode> spNewNode=NULL;
- hr = spXmldoc->get_documentElement(&spRoot);
- spRoot->get_xml(&bstrXml);
- AfxMessageBox(L"1, 原始的XML");
- AfxMessageBox(bstrXml);
- spXmldoc->createElement(L"book", &spTheBook);
- spXmldoc->createElement(L"name", &spTheElem);
- spTheElem->put_text(L"新书");
- spTheBook->appendChild(spTheElem, &spNewNode);
- spTheElem.Release();
- spNewNode.Release();
- spXmldoc->createElement(L"price", &spTheElem);
- spTheElem->put_text(L"20");
- spTheBook->appendChild(spTheElem, &spNewNode);
- spTheElem.Release();
- spNewNode.Release();
- spXmldoc->createElement(L"memo", &spTheElem);
- spTheElem->put_text(L"新书的更好看。");
- spTheBook->appendChild(spTheElem, &spNewNode);
- spNewNode.Release();
- spTheElem.Release();
- spRoot->appendChild(spTheBook, &spNewNode);
- spNewNode.Release();
- spTheBook.Release();
- spRoot->get_xml(&bstrXml);
- AfxMessageBox(L"2, 新建一本书完成");
- AfxMessageBox(bstrXml);
- --- 新建一本书完成 ----
- --- 下面对《哈里波特》做一些修改。 ----
- --- 查询找《哈里波特》----
- CComPtr<IXMLDOMNode> spTheNode=NULL;
- spRoot->selectSingleNode(L"/books/book[name='哈里波特']", &spTheNode);
- hr=spTheNode.QueryInterface(&spTheBook);
- spTheNode.Release();
- spTheBook->get_xml(&bstrXml);
- AfxMessageBox(L"3,《哈里波特》的XML");
- AfxMessageBox(bstrXml);
- --- 此时修改这本书的价格 -----
- CComPtr<IXMLDOMNodeList> spNodeList=NULL;
- CComPtr<IXMLDOMNode> spListItem=NULL;
- spTheBook->get_childNodes(&spNodeList);
- spNodeList->get_item(1, &spListItem);
- spNodeList.Release();
- spListItem->put_text(L"15");
- --- 另外还想加一个属性id,值为B01 ----
- CComVariant varId(L"B01");
- spTheBook->setAttribute(L"id", varId);
- varId.Clear();
- spTheBook->get_xml(&bstrXml);
- spTheBook.Release();
- AfxMessageBox(L"4, 对《哈里波特》修改完成。");
- AfxMessageBox(bstrXml);
- --- 对《哈里波特》修改完成。 ----
- --- 要用id属性删除《三国演义》这本书 ----
- spRoot->selectSingleNode(L"/books/book[@id='B02']", &spTheNode);
- hr=spTheNode.QueryInterface(&spTheBook);
- spTheNode.Release();
- spTheBook->get_xml(&bstrXml);
- AfxMessageBox(L"5, 《三国演义》的XML");
- AfxMessageBox(bstrXml);
- CComPtr<IXMLDOMNode> spParentNode=NULL;
- spTheBook->get_parentNode(&spParentNode);
- spParentNode->removeChild(spTheBook, &spTheNode);
- spTheNode.Release();
- spParentNode.Release();
- spTheBook.Release();
- spRoot->get_xml(&bstrXml);
- AfxMessageBox(L"6, 删除《三国演义》后的XML");
- AfxMessageBox(bstrXml);
- --- 再将所有价格低于10的书删除 ----
- spRoot->selectNodes(L"/books/book[price<10]", &spNodeList);
- CComQIPtr<IXMLDOMSelection> spSomeBooks=spNodeList;
- spNodeList.Release();
- spSomeBooks->removeAll();
- spSomeBooks.Release();
- spXmldoc->get_xml(&bstrXml);
- AfxMessageBox(L"7, 已经删除价格低于10的书");
- AfxMessageBox(bstrXml);
- spRoot.Release();
- bstrXml.Empty();
- //spXmldoc->save(varXmlFile); //保存xml。
- }
- varXmlFile.ClearToZero();
- }
- spXmldoc.Release();
- CoUninitialize();
- }
a.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <books>
- <book>
- <name>哈里波特</name>
- <price>10</price>
- <memo>这是一本很好看的书。</memo>
- </book>
- <book id="B02">
- <name>三国演义</name>
- <price>10</price>
- <memo>四大名著之一。</memo>
- </book>
- <book id="B03">
- <name>水浒</name>
- <price>6</price>
- <memo>四大名著之一。</memo>
- </book>
- <book id="B04">
- <name>红楼</name>
- <price>5</price>
- <memo>四大名著之一。</memo>
- </book>