Click here to Skip to main content
13,142,646 members (51,628 online)
Click here to Skip to main content
Add your own
alternative version


163 bookmarked
Posted 16 Jul 2007

CXml - A Wrapping Class for MSXML 3.0/4.0/5.0/6.0

, 10 Jan 2013
Rate this:
Please Sign up or sign in to vote.
This wrapping class will try to use the latest version of MSXML in the machine, and it is easy because of using auto_ptr.


MSXML, a window component shipped with Windows / Office and other Microsoft products, exists in all Windows platforms. But there are different versions of MSXML, from 2.6 to 6.0, which causes a lot of problems.

This is a wrapping class library for MSXML 3.0/4.0/5.0/6.0 consisting of resolving the above problem -- you don't need to worry about the available MSXML version on different machines any more. Also it provides an easy-to-use interface -- each node in the XML is considered an object and you can use some code like below to locate a node.  


Sample Code

Please find the sample code in the demo project.


Using the Code

Copy all the files in the /CXml/*.* directory and add them into your project.

#include "Xml.h"
using namespace JWXml;

Here, I have added a namespace for the classes, you can change it as you like.

MSXML Version

The class will try to choose the version of MSXML in the following order:

hr = (hr == S_OK) ? hr : m_pDoc.CreateInstance( __uuidof(MSXML2::DOMDocument60) );
hr = (hr == S_OK) ? hr : m_pDoc.CreateInstance( __uuidof(MSXML2::DOMDocument30) );
hr = (hr == S_OK) ? hr : m_pDoc.CreateInstance( __uuidof(MSXML2::DOMDocument50) );
hr = (hr == S_OK) ? hr : m_pDoc.CreateInstance( __uuidof(MSXML2::DOMDocument40) );
hr = (hr == S_OK) ? hr : m_pDoc.CreateInstance( __uuidof(MSXML2::DOMDocument26) );
hr = (hr == S_OK) ? hr : m_pDoc.CreateInstance( __uuidof(MSXML2::DOMDocument) );

Classes Overview


class CXml
    friend class CXsl;


    MSXML2::IXMLDOMDocument2Ptr m_pDoc;
    CString m_strFilePath;
    MSXML_VERSION m_emVersion;
    std::map< CString, CString> m_mpNamespace;

    BOOL CreateInstance(void);

    // Open XML file
    BOOL Open(LPCTSTR lpszXmlFilePath);

    // Create a new XML file
    BOOL Create( LPCTSTR lpszRootName = _T("xmlRoot")
        , LPCTSTR lpszPrefix = _T("")
        , LPCTSTR lpszNamespaceURI = _T("")

    // Load XML string
    BOOL LoadXml(LPCTSTR lpszXmlContent);

    // save XML file
    BOOL Save(LPCTSTR lpszFilePath);

    // save XML file with formatted output
    BOOL SaveWithFormatted(LPCTSTR lpszFilePath = NULL, 
            LPCTSTR lpszEncoding = _T("UTF-8"));

    // close XML file
    void Close(void);

    CString GetXmlFile(void) const;

    // Encode the binary data into string
    CString Base64Encode( LPBYTE pBuf, ULONG ulSize);

    // Decode the string into binary data
    BOOL Base64Decode( CString strIn, LPBYTE pBuf, LONG & lSize);

    // namespace
    void AddSelectionNamespace( LPCTSTR lpszPrefix, LPCTSTR lpszURI);

    // get the root element of
    CXmlNodePtr GetRoot(void);

    // get single node by XPath
    CXmlNodePtr SelectSingleNode(LPCTSTR lpszPath);

    // get nodes by XPath
    CXmlNodesPtr SelectNodes(LPCTSTR lpszPath);

    // create node
    CXmlNodePtr CreateNode(LPCTSTR lpszName
        , LPCTSTR lpszPrefix = _T("")
        , LPCTSTR lpszNamespaceURI = _T("")

    // get the current version of MSXML
    MSXML_VERSION GetVersion(void) const;


class CXmlNode
    friend class CXml;
    friend class CXmlNode;
    friend class CXmlNodes;

    MSXML2::IXMLDOMNodePtr m_pNode;

    CXmlNode( MSXML2::IXMLDOMNodePtr pNode);

    BOOL _GetValue(CString & strValue) const;
    BOOL _SetValue(CString & strValue) const;

    BOOL _GetAttribute( CString & strName, CString & strValue) const;
    BOOL _SetAttribute( CString & strName IN
                      , CString & strValue IN
                      , CString & strPrefix IN
                      , CString & strNamespaceURI IN
                      ) const;


    CXmlNode(const CXmlNode & refNode IN);
    CXmlNode(const CXmlNodePtr pNode IN);

    CXmlNodePtr operator = (CXmlNodePtr pNode);
    CXmlNode & operator = (const CXmlNode & refNode);

    BOOL IsNull(void) const;     // Whether the current element exist
    CString GetName(void) const;// Get the name of the current node
    CXmlNode & Detach(void);    // Detach the current node
    void Release(void);    // Release this node

    CXmlNodePtr GetChild( CString strName, BOOL bBuildIfNotExist = TRUE);
    CXmlNodePtr NewChild( CString strName );
    CXmlNodePtr GetParent(void);
    CXmlNodesPtr GetChildren();
    void AttachChild( CXmlNodePtr & pChildNode);
    void AttachChild( CXmlNode & refChildNode);
    BOOL HasChildren(void);
    BOOL RemoveChildren(void);

    CString    GetAttribute( CString strName, LPCTSTR lpszDefault = NULL) const;
    bool    GetAttribute( CString strName, bool bDefault) const;
    int        GetAttribute( CString strName, int nDefault) const;
    long    GetAttribute( CString strName, long lDefault) const;
    __int64    GetAttribute( CString strName, __int64 llDefault) const;
    float    GetAttribute( CString strName, float fDefault) const;
    double    GetAttribute( CString strName, double dDefault) const;
    DWORD    GetAttribute( CString strName, DWORD dwDefault) const;

    BOOL    SetAttribute( CString strName, LPCTSTR lpszValue ,
            CString strPrefix = _T(""), CString strNamespaceURI = _T(""));
    BOOL    SetAttribute( CString strName, bool bValue ,
            CString strPrefix = _T(""), CString strNamespaceURI = _T(""));
    BOOL    SetAttribute( CString strName, int nValue ,
            CString strPrefix = _T(""), CString strNamespaceURI = _T(""));
    BOOL    SetAttribute( CString strName, long lValue ,
            CString strPrefix = _T(""), CString strNamespaceURI = _T(""));
    BOOL    SetAttribute( CString strName, __int64 llValue ,
            CString strPrefix = _T(""), CString strNamespaceURI = _T(""));
    BOOL    SetAttribute( CString strName, float fValue ,
            CString strPrefix = _T(""), CString strNamespaceURI = _T(""));
    BOOL    SetAttribute( CString strName, double dValue ,
            CString strPrefix = _T(""), CString strNamespaceURI = _T(""));
    BOOL    SetAttribute( CString strName, DWORD dwValue ,
            CString strPrefix = _T(""), CString strNamespaceURI = _T(""));

    BOOL RemoveAttribute( CString strName );

    CString    GetValue( LPCTSTR lpszDefault = NULL ) const;
    bool    GetValue( bool bDefault ) const;
    int        GetValue( int nDefault) const;
    long    GetValue( long lDefault) const;
    __int64    GetValue( __int64 llDefault) const;
    float    GetValue( float fDefault) const;
    double    GetValue( double dDefault) const;
    DWORD    GetValue( DWORD dwDefault) const;

    BOOL    SetValue( LPCTSTR lpszValue );
    BOOL    SetValue( bool bValue );
    BOOL    SetValue( int nValue );
    BOOL    SetValue( long lValue );
    BOOL    SetValue( __int64 llValue );
    BOOL    SetValue( float fValue );
    BOOL    SetValue( double dValue );
    BOOL    SetValue( DWORD dwValue );

    CXmlNodePtr SelectSingleNode(LPCTSTR lpszPath);
    CXmlNodesPtr SelectNodes(LPCTSTR lpszPath);

    CString GetOuterXml(void) const;
    CString GetInnerXml(void) const;


class CXmlNodes
    friend class CXml;
    friend class CXmlNode;
    friend class CXmlNodes;

    CXmlNodes( const CXmlNodes & refNodes );
    CXmlNodes( CXmlNodesPtr pNodes );

    CXmlNodesPtr operator = (CXmlNodesPtr pNodes);
    CXmlNodes & operator = (const CXmlNodes & refNodes);
    CXmlNodePtr operator[] ( LONG lIndex );
    CXmlNodePtr operator[] ( LPCTSTR lpszName );

    LONG GetCount(void);
    void Release(void);

    CXmlNodePtr GetItem( LONG nIndex );
    CXmlNodePtr GetItem( LPCTSTR lpszName );

    CXmlNodes(MSXML2::IXMLDOMNodeListPtr pNodeList);
    MSXML2::IXMLDOMNodeListPtr m_pNodeList;



class CXsl

    // Open XSL file
    BOOL Open(LPCTSTR lpszXslFilePath);

    // close XSL file
    void Close(void);

    // transform to file
    BOOL TransformToFile( CXml & objXml, LPCTSTR lpszFilePath);

    // add a parameter
    BOOL AddParameter( LPCTSTR lpszParamName, LPCTSTR lpszParamValue, 
            LPCTSTR lpszNamespaceURI = NULL);

    MSXML2::IXSLTemplatePtr m_pIXSLTemplate;
    MSXML2::IXMLDOMDocument2Ptr m_pStyleSheet;
    MSXML2::IXSLProcessorPtr m_pIXSLProcessor;


  • v2.0
    • Created: 2007-07-16
  • v2.1
    • Added LoadXml method
    • Added GetVersion method
    • Added const for GetXXX methods
    • Defined ASSERT as ATLASSERT for ATL
    • Defined TRACE as ATLTRACE for ATL
  • V2.2
    • Added the parameter lpszRootName for CXml::Open
    • Removed CXml::GetLastError
    • Added CXml::AddNamespace
    • Added two new overrides for CXml::CreateNode with namespace support
  • V3.0
    • Added another copy constructor for CXmlNode and CXmlNodes
    • Added const modifier for some variables
    • Added CXmlNode::GetInnerXml
    • Added CXmlNode::GetOuterXml
    • Added CXml::Create
    • Changed the MSXML version for Create to 6.0 -> 3.0 -> 5.0 -> 4.0
    • Added namespace support for attributes
    • Added a new class named CXsl
  • V3.1
    • Add method CXml::SaveWithFormatted (Thanks to roel_)
    • Reuse CXml::SaveStreamToFile in CXsl::TransformToFile
    • Add CXsl::AddParameter to allow passing parameters to XSLT
    • Use std::tr1::shared_ptr if exists instead of std::auto_ptr
    • Change namespace from Generic to JWXml 
  • V3.2
    • Bug fix for the Create method usage in demo.
    • Upgrade to VS2010


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Team Leader
China China
Jerry is from China. He was captivated by computer programming since 13 years old when first time played with Q-Basic.

  • Windows / Linux & C++

  • iOS & Obj-C

  • .Net & C#

  • Flex/Flash & ActionScript

  • HTML / CSS / Javascript

  • Gaming Server programming / video, audio processing / image & graphics

Contact: vcer(at)
Chinese Blog:

You may also be interested in...

Comments and Discussions

QuestionGreat work! Pin
nilaysoft7-Aug-17 20:55
membernilaysoft7-Aug-17 20:55 
Suggestionreport for memory leak issue. Pin
seoulpunk17-Apr-16 20:14
professionalseoulpunk17-Apr-16 20:14 
GeneralRe: report for memory leak issue. Pin
Member 1186094825-Apr-16 4:03
memberMember 1186094825-Apr-16 4:03 
Bug求教,出现红色大X Pin
wuxianzhong13-Jul-14 5:59
memberwuxianzhong13-Jul-14 5:59 
GeneralRe: 求教,出现红色大X Pin
Jerry.Wang17-Sep-14 22:27
memberJerry.Wang17-Sep-14 22:27 
QuestionMissing some information about Canonilization Pin
KarstenK4-Nov-13 20:57
memberKarstenK4-Nov-13 20:57 
GeneralMy vote of 5 Pin
maplewang22-Jan-13 15:59
membermaplewang22-Jan-13 15:59 
GeneralMy vote of 5 Pin
skyformat99@gmail.com11-Jan-13 17:55
memberskyformat99@gmail.com11-Jan-13 17:55 
GeneralRe: My vote of 5 Pin
Jerry.Wang12-Jan-13 13:50
memberJerry.Wang12-Jan-13 13:50 
GeneralMy vote of 5 Pin
H.Brydon10-Jan-13 8:51
memberH.Brydon10-Jan-13 8:51 
Question这个项目有人在版本低于6.0的MSXML环境下用过吗? Pin
dothan00925-Feb-12 1:37
memberdothan00925-Feb-12 1:37 
Question没有一个比较简便的demo么? Pin
yanzhiwei1475-Feb-12 20:47
memberyanzhiwei1475-Feb-12 20:47 
GeneralMy vote of 5 Pin
jerry_wangjh11-Nov-11 20:39
memberjerry_wangjh11-Nov-11 20:39 
GeneralMy vote of 5 Pin
tankfun12-Sep-11 23:49
membertankfun12-Sep-11 23:49 
GeneralRe: My vote of 5 Pin
Li Zhaoming28-Jul-16 3:51
memberLi Zhaoming28-Jul-16 3:51 
Generalnew function - GetXML() Pin
Master^Tristar30-Mar-11 19:28
memberMaster^Tristar30-Mar-11 19:28 
GeneralRe: new function - GetXML() Pin
Jerry.Wang12-Apr-11 18:45
memberJerry.Wang12-Apr-11 18:45 
GeneralRe: new function - GetXML() Pin
hazywxin226-May-11 5:06
memberhazywxin226-May-11 5:06 
GeneralMy vote of 5 Pin
Jhomes14-Feb-11 11:21
memberJhomes14-Feb-11 11:21 
AnswerAdded two new functions: GetAttributeCount Pin
Lars [Large] Werner19-Dec-10 9:49
memberLars [Large] Werner19-Dec-10 9:49 
Generaland GetAttributeByIndex Pin
Lars [Large] Werner19-Dec-10 9:51
memberLars [Large] Werner19-Dec-10 9:51 
GeneralRe: and GetAttributeByIndex Pin
Jerry.Wang12-Apr-11 18:48
memberJerry.Wang12-Apr-11 18:48 
QuestionIf I call _tsplitpath first then call CXmlNode::SetAttribute(strName, lpszValue). It's default parameter will have some value. why? Pin
silvonli15-Nov-10 21:56
membersilvonli15-Nov-10 21:56 
GeneralGood job, if you provide more sample is better Pin
maplewang26-Oct-10 0:59
membermaplewang26-Oct-10 0:59 
Question不支持命名空间? Pin
hellohuhu6-Apr-10 23:26
memberhellohuhu6-Apr-10 23:26 
AnswerRe: 不支持命名空间? Pin
Jerry.Wang7-Jul-10 16:34
memberJerry.Wang7-Jul-10 16:34 
Question如何解决缩进的问题?? Pin
zhuliyan23-Feb-10 21:39
memberzhuliyan23-Feb-10 21:39 
AnswerRe: 如何解决缩进的问题?? Pin
Jerry.Wang8-Mar-10 16:35
memberJerry.Wang8-Mar-10 16:35 
Question如何解决缩进的问题?? Pin
zhuliyan23-Feb-10 21:37
memberzhuliyan23-Feb-10 21:37 
GeneralHeap corruption detected Pin
Snakefoot8-Dec-09 11:10
memberSnakefoot8-Dec-09 11:10 
QuestionSaveWithFormatted 保存为UTF-8编码文件的时候如何带签名? Pin
topexcel18-Nov-09 4:09
membertopexcel18-Nov-09 4:09 
AnswerRe: SaveWithFormatted 保存为UTF-8编码文件的时候如何带签名? Pin
Jerry.Wang18-Nov-09 15:33
memberJerry.Wang18-Nov-09 15:33 
GeneralRe: SaveWithFormatted 保存为UTF-8编码文件的时候如何带签名? Pin
topexcel20-Dec-09 16:16
membertopexcel20-Dec-09 16:16 
GeneralUsage under Windows CE Pin
Yoisel14-Nov-09 5:16
memberYoisel14-Nov-09 5:16 
GeneralRe: Usage under Windows CE Pin
Jerry.Wang14-Nov-09 22:00
memberJerry.Wang14-Nov-09 22:00 
GeneralRe: Usage under Windows CE Pin
Yoisel17-Nov-09 4:47
memberYoisel17-Nov-09 4:47 
GeneralVery easy to use after reading the code samples Pin
Snakefoot24-Sep-09 23:33
memberSnakefoot24-Sep-09 23:33 
GeneralSpecial characters Pin
Member 2888148-May-09 13:42
memberMember 2888148-May-09 13:42 
QuestionHow can I change a node's name? Pin
sheng.wang1-Apr-09 17:20
membersheng.wang1-Apr-09 17:20 
General当用创建XML文件时存在虫虫. Pin
linshengfeng7-Mar-09 1:28
memberlinshengfeng7-Mar-09 1:28 
GeneralRe: 当用创建XML文件时存在虫虫. Pin
Jerry.Wang7-Mar-09 2:20
memberJerry.Wang7-Mar-09 2:20 
GeneralIs it better to use vector<cxmlnodeptr> to replace CXmlNodes? [modified]</cxmlnodeptr> Pin
jerry_wangjh27-Feb-09 15:12
memberjerry_wangjh27-Feb-09 15:12 
QuestionPerformance problem Pin
poney8-Dec-08 16:17
memberponey8-Dec-08 16:17 
AnswerIf there are hundreds of nodes in the xml, or the xml file is very huge. SAX is better. Pin
Jerry.Wang8-Dec-08 19:35
memberJerry.Wang8-Dec-08 19:35 
NewsA bug was found in the DEMO program Pin
Jerry.Wang4-Dec-08 14:40
memberJerry.Wang4-Dec-08 14:40 
GeneralGet whole xml string method Pin
poney4-Dec-08 14:20
memberponey4-Dec-08 14:20 
GeneralRe: Get whole xml string method Pin
Jerry.Wang4-Dec-08 14:38
memberJerry.Wang4-Dec-08 14:38 
NewsCool Articles about This Topic [modified] Pin
codemobile31-Oct-08 20:08
membercodemobile31-Oct-08 20:08 
GeneralRe: Cool Articles about This Topic Pin
KnDol10-Nov-08 22:09
memberKnDol10-Nov-08 22:09 
GeneralSome more API comments... Pin
roel_12-Oct-08 22:19
memberroel_12-Oct-08 22:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.170915.1 | Last Updated 10 Jan 2013
Article Copyright 2007 by Jerry.Wang
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid