使用MsXML存取XML(2)
与JavaScript相比而言,在C++中调用COM比较麻烦,MsXML库是一组COM动态库,这意味Visual C++应用程序必须以COM调用方式调用MsXML组件。
下面是实现存取persons.xml文件的Visual C++版本。
需要导入“msxml4.dll”组件库
【程序 6-8】使用MsXML读写XML文件
1. 01 #include "stdafx.h"
2. 02 #include "comutil.h"
3. 03 #include <clocale>
4. 04
5. 05 #import "msxml4.dll"
6. 06
7. 07 void WritePerson(MSXML2::IXMLDOMDocument2Ptr pDocument,
8. MSXML2::IXMLDOMNodePtr pParentNode, CString name, long age)
9. 08 {
10. 09 //创建一个<person>节点
11. 10 MSXML2::IXMLDOMElementPtr pPersonNode =
pDocument->createElement(_T("person"));
12. 11 pParentNode->appendChild(pPersonNode);
13. 12
14. 13 //写入name
15. 14 MSXML2::IXMLDOMElementPtr pPersonNameNode =
pDocument->createElement(_T("name"));
16. 15 pPersonNameNode->text = _bstr_t(name);
17. 16
18. 17 //写入age
19. 18 MSXML2::IXMLDOMElementPtr pPersonAgeNode =
pDocument->createElement(_T("age"));
20. 19 pPersonAgeNode->text = _bstr_t(age);
21. 20
22. 21 pPersonNode->appendChild(pPersonNameNode);
23. 22 pPersonNode->appendChild(pPersonAgeNode);
24. 23 }
25. 24
26. 25 void WritePersons()
27. 26 {
28. 27 MSXML2::IXMLDOMDocument2Ptr pXMLDocument;
29. 28 pXMLDocument.CreateInstance(__uuidof(MSXML2::DOMDocument));
30. 29 MSXML2::IXMLDOMElementPtr pPersonsNode =
31. pXMLDocument->createElement(_T("persons"));
32. 30 pXMLDocument->appendChild(pPersonsNode);
33. 31
34. 32 WritePerson(pXMLDocument, pPersonsNode, _T("佟湘玉"), 28);
35. 33 WritePerson(pXMLDocument, pPersonsNode, _T("白展堂"), 27);
36. 34
37. 35 pXMLDocument->save(_T("persons.xml"));
38. 36 }
39. 37
40. 38 void ReadPersons()
41. 39 {
42. 40 MSXML2::IXMLDOMDocument2Ptr pXMLDocument;
43. 41 pXMLDocument.CreateInstance(__uuidof(MSXML2::DOMDocument));
44. 42
45. 43 pXMLDocument->load(_T("persons.xml"));
46. 44
47. 45 MSXML2::IXMLDOMElementPtr pRootNode =
pXMLDocument->documentElement;
48. 46 //查找<person>节点
49. 47 MSXML2::IXMLDOMNodeListPtr pPersonNodes =
pRootNode->selectNodes(_T("person"));
50. 48
51. 49 CString s;
52. 50 long size = pPersonNodes->length;
53. 51
54. 52 for(int i = 0; i < size; i++)
55. 53 {
56. 54 MSXML2::IXMLDOMNodePtr pPersonNode =
pPersonNodes->item[i];
57. 55
58. 56 MSXML2::IXMLDOMNodePtr pNameNode =
pPersonNode->selectSingleNode(_T("name"));
59. 57 MSXML2::IXMLDOMNodePtr pAgeNode =
pPersonNode->selectSingleNode(_T("age"));
60. 58
61. 59 s.Format(_T("%sname: %s\tage: %s\r\n"),
s, (LPCTSTR)pNameNode->
62. text, (LPCTSTR)pAgeNode->text);
63. 60 }
64. 61
65. 62 _tprintf(s);
66. 63 }
67. 64
68. 65 int _tmain()
69. 66 {
70. 67 setlocale(LC_ALL, "chs");
71. 68
72. 69 HRESULT hr;
73. 70 hr = ::CoInitialize(NULL);
74. 71
75. 72 WritePersons();
76. 73 ReadPersons();
77. 74
78. 75 ::CoUninitialize();
79. 76 return 0;77 }
运行结果如图6-27所示。
|
图6-27 运行结果 |
在Visual C++中,调用COM组件比较省力、安全的办法是使用#import方式。另外,MsXML的版本不同,其提供的DLL文件名也不同,如MSXML 4.0对应的DLL为"msxml4.dll"。细心的读者可能会发现,一旦在程序中导入了msxml4.dll并build(生成)一次项目,在程序中就可以自动引入一些类,如:MSXML2::IXMLDOMDocument2Ptr,MSXML2是一个C++名字空间,IXMLDOMDocument2Ptr则是一个封装了IXMLDOMDocument对象操作的智能指针类。好奇的读者可以选择"IXMLDOMDocument2Ptr",并查看其定义,就可以跟踪到Debug目录下一个叫着msxml4.tlh的头文件,它是由Visual C++从msxml4.dll中自动提取并生成的C++头文件,与此一起生成的还有其他的文件,如msxml4.tli等。