MSXML2::IXMLDOMDocumentPtr pDoc;MSXML2::IXMLDOMElementPtr xmlRoot ;// 创建DOMDocument对象HRESUL T hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument40));if ( ! SUCCEEDED(hr)){MessageBox( " 无法创建DOMDocument对象,请检查是否安装了MS XML Parser 运行库! " );return ;}// 根节点的名称为Book// 创建元素并添加到文档中xmlRoot = pDoc -> createElement((_bstr_t) " Book " );// 设置属性xmlRoot -> setA ttribute( " id " ,( const char * )m_strId);pDoc -> appendChild(xmlRoot);MSXML2::IXMLDOMElementPtr pNode;// 添加“author”元素pNode = pDoc -> createElement((_bstr_t) " A uthor " );pNode -> Puttext((_bstr_t)( const char * )m_strA uthor);xmlRoot -> appendChild(pNode);// 添加“Title”元素pNode = pDoc -> createElement( " Title " );pNode -> Puttext(( const char * )m_strTitle);xmlRoot -> appendChild(pNode);// 保存到文件// 如果不存在就建立,存在就覆盖pDoc -> save( " d://he.xml " );------------------------------------------------------------------------------------------------------------------------------------------------MSXML2::IXMLDOMDocumentPtr pDoc;HRESUL T hr;hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument40));if (FA ILED(hr)){MessageBox( " 无法创建DOMDocument对象,请检查是否安装了MS XML Parser 运行库! " );return ;}// 加载文件pDoc -> load( " d://he.xml " );MSXML2::IXMLDOMNodePtr pNode;// 在树中查找名为Book的节点," // "表示在任意一层查找pNode = pDoc -> selectSingleNode( " //Book " );MSXML2::DOMNodeType nodeType;// 得到节点类型pNode -> get_nodeType( & nodeType);// 节点名称CString strName;strName = ( char * )pNode -> GetnodeName();// 节点属性,放在链表中MSXML2::IXMLDOMNamedNodeMapPtr pA ttrMap = NULL;MSXML2::IXMLDOMNodePtr pA ttrItem;_variant_t variantvalue;pNode -> get_attributes( & pA ttrMap);long count;count = pA ttrMap -> get_length( & count);pA ttrMap -> get_item( 0 , & pA ttrItem);// 取得节点的值pA ttrItem -> get_nodeTypedV alue( & variantvalue);m_strId = ( char * )(_bstr_t)variantvalue;// 添加整个文档的根节点void A ddRootNode( CString strRootNode , CString strText = ""){m_pElement = m_pDoc->createElement( (LPCTSTR)strRootNode );m_pElement ->put_text( _bstr_t( (LPCTSTR)strText) );m_pDoc->appendChild( m_pElement );}三种最流行的开放源码 XML 库是 expat、libxml 和 Xerces。
这三者都是跨平台的,每一种都充当 XSLT 库实现的基础,一旦满足了基本 XML 需要之后,它就会给您一条成长途径。
●expat 是 James Clark 创始的开放源码面向事件的 XML 解析库。
他已经将该项目转让给了 SourceForge 中的一个小组。
有一个 SAX 封装器可供使用。
在许多项目中都可以找到 expat 解析器,如开放源码浏览器 Mozilla、XSLT 处理器 Transformiix 和 RDF 工具 repat。
●libxml 为类似于 SAX 和 DOM 的操作提供了双重方式 API。
它支持对 DTD 的验证,并且在 Gnome 的 XSLT 处理器libxslt中使用。
libxml 经过重写,已作为 libxml(2) 发布,也许还称为libxml2。
这个库的用户应该确保他们拥有了当前版本。
●Xerces 是非常坚固的、拥有大量文档的库,它充当 IBM alphaWorksXML 4C 库的基础。
Xerces 还用于 Apache XSLT 处理器 Xalan 中。
Xerces 支持 DOM、SAX,以及对 DTD 的验证。
最新版本读取并解释了部分“W3C XML 模式推荐”(打算到 2001 年底实现完整的XML 模式支持)。
附:C/C++ 开发人员的解析器库供应商事件文档特点许可证本机与 SAX-带有本机 API 和LGPL(免费)expat JamesClark/expat 小组SAX 封装器的、非常快速的推模型解析器。
libxml Gnome SAX DOM非常强壮;SAX与 DOM 封装器;执行 DTD 验证LGPL(免费)MSXML Microsoft SAX DOM Win32 的Microsoft XML库EULA(免费)Xerces ApacheSoftwareFoundation SAX DOM执行 SAX 及DOM 级别 1 和2;DTD 验证;增加的XML 模式Apache(免费)XTL Vivid Creations SAX DOM带 SAX 和 DOM的基于 STL 的XML 工具箱商业RXP爱丁堡大学-本机验证以 C 编写的了解名称空间的XML 解析器GPL(免费)XML 4C IBMalphaWorks SAX DOM IBM 发起的Xerces 的变体Apache(免费)Oracle XDK 8i Oracle SAX DOM Oracle 主办的用于 C++ 的 XML工具箱非商业Pull Parser Extreme! Lab-本机印地安那大学发起的用于 C++ 的轻量型 XML 工具箱非商业XMLBooster PhiDaNiSoftware -本机解析器发生器,生成 C 源码解析器商业-------------------------------------------------------Boost读取XML配置文件-----------------------------------------------------------------------------------------------------------前两天因工作需要写了个xml配置脚本解析的功能类,虽说有N种方式可以实现,但考虑到Boost库在此方面的易操作性(虽支持不够健全,如Unicode支持等)所以封装了一下,具体如下://CProcessXmlConfigFile.h(此类由Dll导出)#i nclude "stdafx.h"#pragma once#i nclude <boost/noncopyable.hpp>#i nclude <boost/property_tree/ptree.hpp>#i nclude <boost/property_tree/xml_parser.hpp>#i nclude <boost/tuple/tuple.hpp>#i nclude <boost/shared_ptr.hpp>#i nclude <list>#i nclude "header.h"#define MA X_PA NLIST_NUM 9 //默认面板个数#define MA X_FNA ME_LEN 256 //文件名长度宏using namespace boost::property_tree;typedef ptree xmlParser;typedef vector<string> panNames_t;typedef boost::shared_ptr<string> sh_pstr;typedef boost::tuples::tuple<sh_pstr, size_t, sh_pstr> node_t;typedef std::list<node_t > ptree_nodes_t;//////////////////////////////////////////////////////////////////////////class AFX_EXT_CLA SS CProcessXmlConfigFile :private boost::noncopyable{public:virtual ~CProcessXmlConfigFile(void);//获取类唯一实例的静态方法static CProcessXmlConfigFile& instance(const string& xmlfile);//|=======================================|//| 以下为设置xml文件的各方法 |//|=======================================|void getPanListInfo(void);void getTreeInfoOfPan(PanIndex _index);inline panNames_t getPanList(void) const { return m_panobj; }inline ptree_nodes_t getPtreeNodeList(void) const { return m_ptreeobj; }private:CProcessXmlConfigFile(const string& xmlfile);//合理性验证方法[_index:面板索引]bool ICanWork(PanIndex _index);//加载文件[xml文件名<含路径>]bool loadfile(const string& xmlfile);//递归遍历节点目录树函数[nodepath:节点路径<分割符为'/'>]void recursive_print(const string& nodepath);private:xmlParser m_parser; //xml文件解析对象panNames_t m_panobj;//存储面板对象列表//存储当前面板下的树节点对象列表ptree_nodes_t m_ptreeobj;};//CProcessXmlConfigFile.cpp#i nclude "StdA fx.h"#i nclude "ProcessXmlConfigFile.h"#i nclude <iostream>// #i nclude <boost/foreach.hpp>#i nclude <boost/format.hpp>#i nclude <boost/typeof/typeof.hpp>#i nclude <boost/make_shared.hpp>// #i nclude <boost/ref.hpp>// #i nclude <boost/program_options/detail/convert.hpp>// #i nclude <boost/program_options/detail/utf8_codecvt_facet.hpp>// #i nclude <windows.h>// #i nclude <stdlib.h>using namespace std;using namespace boost;//参数默认值..const int iDefaultInt = 0;const string strNullString = "";const char chflag = '/';const string strPan = "doc/pans/pan";const string strflag = "<xmlattr>";const wstring win32_dir_splitchar = L"\\";//////////////////////////////////////////////////////////////////////////CProcessXmlConfig:CProcessXmlConfigFile(const string& xmlfile) {loadfile(xmlfile);m_panobj.clear();m_panobj.reserve(MA X_PA NLIST_NUM);CProcessXmlConfig:~CProcessXmlConfigFile(void){}CProcessXmlConfigFile& CProcessXmlConfig:instance(const string& xmlfile) {static CProcessXmlConfigFile _instance(xmlfile);return _instance;}void CProcessXmlConfig:getPanListInfo( void ){//开始获取.//首先获取总面板节点个数assert(m_parser.get_optional<int>("doc.pans.<xmlattr>.glcount"));//循环获取各节点名称string str = "";auto_t(child, m_parser.get_child("doc.pans"));for (auto_t(t, child.begin()); t != child.end(); ++t){str = t->first;if (str.find("pan") == string::npos)continue;m_panobj.push_back(t->second.data());}}void CProcessXmlConfig:getTreeInfoOfPan( PanIndex _index ){//防御性设计if (!ICanWork(_index))return;//..format fmt("%s-%d");fmt % strPan % _index;m_ptreeobj.clear();recursive_print(fmt.str());}bool CProcessXmlConfig:ICanWork( PanIndex _index ){return (_index >= ST_PhysicalCharacteristics && _index <= ST_Report);}bool CProcessXmlConfig:loadfile(const string& xmlfile){//防御性设计if (xmlfile.empty())return false;//..try//获取当前应用程序路径..wstring strPath(L"");{TCHA R currPath[MA X_FNA ME_LEN+1] = {0};GetModuleFileName(NULL, currPath, MA X_FNA ME_LEN);TCHA R *psz = _tcsrchr(currPath, '\\');if (psz){*psz = '\0'; //取出程序所在的目录lstrcat(currPath, win32_dir_splitchar.c_str());strPath = currPath;}}//加载配置文件.string xmlfilePath = WideToA SCII(strPath.c_str()) + xmlfile;// std::locale oldLocale;// std::locale utf8Locale(oldLocale,// new boost::program_options::detail::utf8_codecvt_facet());read_xml(xmlfilePath, m_parser, xml_parser::no_comments);}catch(std::exception& e){A fxMessageBox(A SCIIToWide(e.what()).c_str());return false;}return true;}//递归遍历xml节点目录树函数..void CProcessXmlConfig:recursive_print( const string& nodepath ){if (nodepath.empty())return;static size_t nproc = 0; //记录递归层次[测试留用]//..string strKey, strKey_, str;auto_t(node, m_parser.get_child(ptree::path_type(nodepath, chflag))); //获取节点信息for (auto_t(pt, node.begin()); pt != node.end(); ++pt){strKey = pt->first;if (strKey.find(strflag) != string::npos)continue;str = pt->second.data();// for (size_t i = 0; i < nproc; ++i)// cout << "\t";// cout << strKey << " = " << (str.empty() ? "empty" : str);//////////////////////////////////////////////////////////////////////////strKey_ = nodepath + "/" + strKey + "/" + strflag;auto_t(attr, m_parser.get_child(ptree::path_type(strKey_, chflag)));//获取节点属性信息for (auto_t(tt, attr.begin()); tt != attr.end(); ++tt){string atkey = tt->first;size_t atnval = tt->second.get_<int>();m_ptreeobj.push_back(make_tuple(sh_pstr(new string(strKey)), atnval, sh_pstr(str.empty() ? new string("empty") : new string(str))));// cout << " <" << atkey << ":" << atnval << ">" << endl;strKey = nodepath + "/" + pt->first;if (atnval > 0) //若子节点数目不止一个则递归遍历{++nproc;recursive_print(strKey);}}}--nproc;// cout << "*****************************************\n";}//主程序文档类中用到了CViewTree来动态加载节点,具体调用如下:instance =&CProcessXmlConfig:instance(xmlfile);BOOST_A SSERT(instance);//获取面板名称列表.instance->getPanListInfo();szPanName = instance->getPanList();if (szPanName.empty())return;// BOOST_FOREA CH(panNames_t::_type& p, szPanName)// A fxMessageBox(CString(p.c_str()));for (size_t i = 0; i < szPanName.size(); ++i){// 首先生成树CViewTree * ptree = new CViewTree;if (!ptree)return;//......FillClassView();//......}FillClassView()方法主体如下:{//防御性设计if (m_objtree.empty())return;if (m_nindex < 0 || m_nindex >= m_objtree.size())return;shared_wnd_ptr pTreeView = m_objtree[m_nindex];if (NULL == pTreeView)return;////////////////////////////////////////////////////////////////////////////加载配置文件并读取配置数据..{//获取当前面板树节点集合信息.BOOST_A SSERT(instance);instance->getTreeInfoOfPan(m_pIndex);ptree_nodes_t ptreenodes = instance->getPtreeNodeList();if (ptreenodes.empty())return ;//动态生成树节点..{int nsub = 0;HTREEITEM item, pitem;std::stack<HTREEITEM> S;S.push(pitem);BOOST_FOREA CH(node_t& node, ptreenodes){size_t n = node.get<1>();string strV al = *node.get<2>();if (strV al.empty() || !pare("empty"))continue;if (nsub > 0){pitem = S.empty() ? NULL : S.top();item = pTreeView->InsertItem(CString(strV al.c_str()), pitem); }else{if (!S.empty()) S.pop();pitem = S.empty() ? NULL : S.top();item = pTreeView->InsertItem(CString(strV al.c_str()), pitem); }if (0 == n) --nsub;else{nsub = n;S.pus。