`
阿尔萨斯
  • 浏览: 4147776 次
社区版块
存档分类
最新评论

[c++]一个对MSXML的封装类 使用C++的Smart Pointer 对MSXML DOM封装,可以方便地访问xml文件

 
阅读更多
<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog.html" frameborder="0" width="728" scrolling="no" height="90"></iframe>

#pragma once
#include "XmlNode.h"


//-------------------------------------------------------------------------
// Classes Name :CXml CXmlNode CXmlNodes
// Author:王嘉 QQ32775973 sky-sea-earth@21cn.com
// CreateTime :2005-10-23
// Memo :Xml结点类库
// Version :v1.4
// Modify:v.1.3
//:修改了几个Bug
//:v.1.4
//:增加了异常处理
//:加入了Base64编码
//:更新的例子程序
//:增加了一个Unicode版本
//:改写部分代码 让它和VC6兼容
//-------------------------------------------------------------------------

class CXml
{
public:
CXml(void);
~CXml(void);

protected:
MSXML2::IXMLDOMDocument2Ptr m_pDoc;
CStringm_strFilePath;

public:
// 打开Xml文件
BOOL Open(CString strXmlFilePath);

// 保存Xml文件
BOOL Save(LPCTSTR lpszFilePath = NULL);

// 关闭Xml文件
void Close(void);

// 获取最近的错误信息
CString GetLastError(void);

// 获取Xml树的根结点
CXmlNodePtr GetRoot(void);

// 选择单个结点
CXmlNodePtr SelectSingleNode(LPCTSTR lpszPath);

// 选择结点集合
CXmlNodesPtr SelectNodes(LPCTSTR lpszPath);

// 判断文件是否存在
static BOOL IsFileExist(CString strFilePath);

// 创建结点
CXmlNodePtr CreateNode(CString strName);

// Base64编码解码
BOOL Base64Decode( CString strIn, LPBYTE & pBuf, LONG & lSize);
CString Base64Encode( LPBYTE pBuf, ULONG ulSize);
};

#include "StdAfx.h"
#include "./xml.h"


CXml::CXml(void)
: m_strFilePath(_T(""))
, m_pDoc(NULL)
{
}

CXml::~CXml(void)
{
Close();
}


//-------------------------------------------------------------------------
// Function Name :IsFileExist[static]
// Parameter(s) :CString strFilePath文件路径和名称
// Return :BOOL
// Memo :判断文件是否存在
//-------------------------------------------------------------------------
BOOL CXml::IsFileExist(CString strFilePath)
{
BOOL bExist = FALSE;
HANDLE hFile = NULL;

hFile = CreateFile( strFilePath
, GENERIC_READ
, FILE_SHARE_READ | FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0
, 0
);

if( hFile != INVALID_HANDLE_VALUE )
{
CloseHandle( hFile );
bExist = TRUE;
}

return (bExist);
}


//-------------------------------------------------------------------------
// Function Name :CreateNode
// Parameter(s) :CString strName结点名称
// Return :CXmlNodePtr
// Memo :创建结点
//-------------------------------------------------------------------------
CXmlNodePtr CXml::CreateNode(CString strName)
{
ASSERT( m_pDoc != NULL );

CXmlNodePtr pChild( new CXmlNode() );

try
{MSXML2::IXMLDOMNodePtr pChildNode = NULL;
pChildNode = m_pDoc->createElement( _bstr_t(strName) );
ASSERT( pChildNode != NULL );
pChild->m_pNode = pChildNode;
RELEASE_PTR(pChildNode);
}
catch ( _com_error e )
{
TRACE( _T("CXml::CreateNode 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
}
return pChild;
}

//-------------------------------------------------------------------------
// Function Name :Open
// Parameter(s) :CString strXmlFilePath文件路径和名称
// Return :BOOL是否成功
// Memo :打开XML文件 如果不存在则创建之
//-------------------------------------------------------------------------
BOOL CXml::Open( CString strXmlFilePath )
{
HRESULT hr = S_OK;

hr = m_pDoc.CreateInstance( __uuidof(MSXML2::DOMDocument40) );
if( !SUCCEEDED(hr) )
{
ASSERT(FALSE);// did u CoInitialize ?did u install MSXML4.0 ?
return FALSE;
}

m_strFilePath = strXmlFilePath;
VARIANT_BOOL vbSuccessful = VARIANT_TRUE;

try
{
m_pDoc->preserveWhiteSpace = VARIANT_FALSE;
m_pDoc->validateOnParse = VARIANT_FALSE;
m_pDoc->setProperty( "NewParser", true);

if( IsFileExist(strXmlFilePath) )
{
vbSuccessful = m_pDoc->load( COleVariant((LPCTSTR)strXmlFilePath) );
}
else
{
MSXML2::IXMLDOMProcessingInstructionPtr pPI = NULL;
pPI = m_pDoc->createProcessingInstruction( _bstr_t(_T("xml")), _bstr_t(_T("version=/"1.0/"")) );
ASSERT( pPI != NULL );

hr = m_pDoc->appendChild(pPI);
ASSERT( SUCCEEDED(hr) );

// 创建根节点
MSXML2::IXMLDOMElementPtr pRoot = NULL;
pRoot = m_pDoc->createElement( _bstr_t(_T("xmlRoot")) );
m_pDoc->appendChild(pRoot);
RELEASE_PTR(pRoot);

vbSuccessful = SUCCEEDED(hr) ? VARIANT_TRUE : VARIANT_FALSE;
}// if_else
}
catch(...)
{
vbSuccessful = FALSE;
ASSERT( FALSE );
}

return vbSuccessful;
}


//-------------------------------------------------------------------------
// Function Name :Close
// Parameter(s) :void
// Return :void
// Memo :关闭
//-------------------------------------------------------------------------
void CXml::Close(void)
{
RELEASE_PTR(m_pDoc);
}

//-------------------------------------------------------------------------
// Function Name :GetLastError
// Parameter(s) :void
// Return :CString
// Memo :获取最后的出错信息
//-------------------------------------------------------------------------
CString CXml::GetLastError(void)
{
ASSERT( m_pDoc != NULL );

HRESULT hr = S_OK;
MSXML2::IXMLDOMParseErrorPtr pIParseError = NULL;

hr = m_pDoc->get_parseError(&pIParseError);
ASSERT( SUCCEEDED(hr) );

CString strRet;
if( pIParseError != NULL )
{
BSTR bstr = NULL;
hr = pIParseError->get_reason(&bstr);
ASSERT( SUCCEEDED(hr) );

strRet = (LPCTSTR)_bstr_t( bstr, true);

if( bstr != NULL )
{
SysFreeString(bstr);
bstr = NULL;
}

RELEASE_PTR(pIParseError);
}

return strRet;
}

//-------------------------------------------------------------------------
// Function Name :GetRoot
// Parameter(s) :
// Return :
// Memo :获取根节点
//-------------------------------------------------------------------------
CXmlNodePtr CXml::GetRoot(void)
{
ASSERT( m_pDoc != NULL );

CXmlNodePtr pNode( new CXmlNode() );

try
{
MSXML2::IXMLDOMElementPtr pElement = NULL;
HRESULT hr = m_pDoc->get_documentElement(&pElement);
ASSERT( SUCCEEDED(hr) );
ASSERT( pElement != NULL );

pNode->m_pNode = pElement;
RELEASE_PTR(pElement);
}
catch ( _com_error e )
{
TRACE( _T("CXml::GetRoot 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
}

return pNode;
}

//-------------------------------------------------------------------------
// Function Name :Save
// Parameter(s) :LPCTSTR lpszFilePath[in] 保存的位置
// Return :BOOL
// Memo :保存Xml文件
//-------------------------------------------------------------------------
BOOL CXml::Save(LPCTSTR lpszFilePath /* = NULL */)
{
ASSERT( m_pDoc != NULL );

HRESULT hr = S_OK;
try
{
if( lpszFilePath == NULL )
hr = m_pDoc->save( COleVariant((LPCTSTR)m_strFilePath) );
else
hr = m_pDoc->save( _variant_t( lpszFilePath ) );
}
catch( _com_error e )
{
TRACE( _T("CXml::Save 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
return FALSE;
}

return SUCCEEDED(hr);
}

//-------------------------------------------------------------------------
// Function Name :SelectSingleNode
// Parameter(s) :LPCTSTR strPath 路径名
// Return :CXmlNodePtr
// Memo :取单个节点
//-------------------------------------------------------------------------
CXmlNodePtr CXml::SelectSingleNode(LPCTSTR lpszPath)
{
ASSERT( m_pDoc != NULL );

CXmlNodePtr pNode ( new CXmlNode() );

if( !GetRoot()->IsNull() )
(*pNode) = GetRoot()->SelectSingleNode(lpszPath);

return pNode;
}

//-------------------------------------------------------------------------
// Function Name :SelectNodes
// Parameter(s) :LPCTSTR strPath路径名
// Return :CXmlNodesPtr
// Memo :取结点集合
//-------------------------------------------------------------------------
CXmlNodesPtr CXml::SelectNodes(LPCTSTR lpszPath)
{
ASSERT( m_pDoc != NULL );

CXmlNodesPtr pNodes( new CXmlNodes() );

if( !GetRoot()->IsNull() )
(*pNodes) = GetRoot()->SelectNodes(lpszPath);

return pNodes;
}

//-------------------------------------------------------------------------
// Function Name :EncodeBase64
// Parameter(s) :LPBYTE *pBuf首地址
//:ULONG ulSize大小
// Return :CString编码后的结果
// Memo :堆二进制数据编码成Base64格式
//-------------------------------------------------------------------------
CString CXml::Base64Encode(LPBYTE pBuf, ULONG ulSize)
{
ASSERT( m_pDoc != NULL );
ASSERT( pBuf != NULL );

CString strRet = _T("");
try
{
MSXML2::IXMLDOMElementPtr pElement = NULL;
pElement = m_pDoc->createElement( _bstr_t(_T("Base64")) );
ASSERT( pElement != NULL );

HRESULT hr = S_OK;
hr = pElement->put_dataType( _bstr_t(_T("bin.base64")) );
ASSERT( SUCCEEDED(hr) );

SAFEARRAY * pAry = SafeArrayCreateVector( VT_UI1, 0L, ulSize);
::memcpy( pAry->pvData, pBuf, ulSize);

VARIANT var;
VariantInit(&var);
var.parray = pAry;
var.vt = VT_ARRAY | VT_UI1;
pElement->nodeTypedValue = var;

BSTR bstr = NULL;
hr = pElement->get_text( &bstr );
ASSERT( SUCCEEDED(hr) );
strRet = (LPCTSTR)_bstr_t( bstr, true);

if( bstr != NULL )
{
SysFreeString(bstr);
bstr = NULL;
}

RELEASE_PTR(pElement);
}
catch ( _com_error e )
{
TRACE( _T("CXml::Base64Encode 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
}

return strRet;
}

//-------------------------------------------------------------------------
// Function Name :Base64Decode
// Parameter(s) :CString strInBase64编码
//:LPBYTE pBuf缓冲区首地址
//:ULONG &ulSize缓冲区大小
// Return :BOOL
// Memo :将Base64编码解码为二进制形式
//注意!此函数的缓冲区需要在函数调用完后删除
//-------------------------------------------------------------------------
BOOL CXml::Base64Decode(CString strIn, LPBYTE & pBuf, LONG &lSize)
{
ASSERT( m_pDoc != NULL );

try
{
MSXML2::IXMLDOMElementPtr pElement = NULL;
pElement = m_pDoc->createElement( _bstr_t(_T("Base64")) );
ASSERT( pElement != NULL );

HRESULT hr = S_OK;
hr = pElement->put_dataType( _bstr_t(_T("bin.base64")) );
ASSERT( SUCCEEDED(hr) );

hr = pElement->put_text( CComBSTR(strIn) );
ASSERT( SUCCEEDED(hr) );

hr = SafeArrayGetUBound( pElement->nodeTypedValue.parray, 1, &lSize);
ASSERT( SUCCEEDED(hr) );
lSize ++;

pBuf = new BYTE[lSize];
memset( pBuf, 0, lSize);

memcpy( pBuf, LPVOID(pElement->nodeTypedValue.parray->pvData), lSize);

RELEASE_PTR(pElement);
}
catch ( _com_error e )
{
TRACE( _T("CXml::Base64Decode 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
return FALSE;
}

return TRUE;
}

#pragma once

#import "msxml4.dll"
#include <memory><br>#include <atlbase.h></atlbase.h></memory>

#ifndef RELEASE_PTR
#define RELEASE_PTR(x)/
if( x != NULL )/
{/
x.Release();/
x = NULL;/
}
#endif

class CXml;
class CXmlNode;
class CXmlNodes;

typedef std::auto_ptr<cxmlnode> CXmlNodePtr;<br>typedef std::auto_ptr<cxmlnodes> CXmlNodesPtr;</cxmlnodes></cxmlnode>

//////////////////////////////////////////////////////////////////////////

#include "./XmlNodes.h"

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

protected:

MSXML2::IXMLDOMNodePtrm_pNode;

CXmlNode( MSXML2::IXMLDOMNodePtr pNode);

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

BOOL _GetAttribute( CString & strName, CString & strValue);
BOOL _SetAttribute( CString & strName, CString & strValue);

public:

// _______________
//______|构造析构|___________________________________________________________________
CXmlNode(void);
CXmlNode( CXmlNode & refNode IN);
~CXmlNode(void);


// _______________
//______|重载 = 号|___________________________________________________________________
CXmlNodePtr operator = ( CXmlNodePtr pNode);
CXmlNode & operator = ( CXmlNode & refNode);

BOOL IsNull(void);// 当前结点是否为空
CString GetName(void);// 获取当前结点名称
CXmlNode & Remove(void);// 将结点与父结点分离
void Release(void);;// 释放节点


// _______________
//______|父子操作|___________________________________________________________________
CXmlNodePtr GetChild( CString strName, BOOL bBuildIfNotExist = TRUE);
CXmlNodePtr NewChild( CString strName );
CXmlNodePtr GetParent(void);
CXmlNodesPtr GetChildren();
void AddChild( CXmlNodePtr & pChildNode);
void AddChild( CXmlNode & refChildNode);
BOOL HasChildren(void);
BOOL RemoveChildren(void);

// _______________
//______|属性操作|___________________________________________________________________
CStringGetAttribute( CString strName, LPCTSTR lpszDefault = NULL);
boolGetAttribute( CString strName, bool bDefault);
intGetAttribute( CString strName, int nDefault);
floatGetAttribute( CString strName, float fDefault);
doubleGetAttribute( CString strName, double dDefault);

BOOLSetAttribute( CString strName, LPCTSTR lpszValue);
BOOLSetAttribute( CString strName, bool bValue);
BOOLSetAttribute( CString strName, int nValue);
BOOLSetAttribute( CString strName, float fValue);
BOOLSetAttribute( CString strName, double dValue);

BOOL RemoveAttribute( CString strName );


// _______________
//______|值操作|___________________________________________________________________
CStringGetValue( LPCTSTR lpszDefault = NULL );
boolGetValue( bool bDefault );
intGetValue( int nDefault);
floatGetValue( float fDefault);
doubleGetValue( double dDefault);

BOOLSetValue( LPCTSTR lpszValue );
BOOLSetValue( bool bValue );
BOOLSetValue( int nValue );
BOOLSetValue( float fValue );
BOOLSetValue( double dValue );


// _______________
//______|XPath查询|___________________________________________________________________
CXmlNodePtr SelectSingleNode(LPCTSTR lpszPath);
CXmlNodesPtr SelectNodes(LPCTSTR lpszPath);


};

#include "StdAfx.h"
#include "./xmlnode.h"


//////////////////////////////////////////////////////////////////////////
#ifndef _tstof
#ifdef _UNICODE

double __cdecl _tstof( const wchar_t *ptr )
{
CHAR astring[20];
WideCharToMultiByte( CP_ACP, 0, ptr, -1, astring, 20, NULL, NULL);
return atof(astring);
}

#else
#define _tstof atof
#endif
#endif
//////////////////////////////////////////////////////////////////////////

//-------------------------------------------------------------------------
// Function Name :_GetValue
// Parameter(s) :CString & strValue IN值
// Return :BOOL是否成功
// Memo :获取当前节点的值
//-------------------------------------------------------------------------
BOOL CXmlNode::_GetValue(CString & strValue OUT)
{
ASSERT( m_pNode != NULL );

HRESULT hr = S_OK;
try
{
if( HasChildren() )
{
// 下面有子结点
ASSERT( FALSE );
return FALSE;
}

BSTR bstr = NULL;
hr = m_pNode->get_text( &bstr );
ASSERT( SUCCEEDED(hr) );
strValue = (LPCTSTR)_bstr_t( bstr, true);

if( bstr != NULL )
{
SysFreeString(bstr);
bstr = NULL;
}
}
catch ( _com_error e )
{
TRACE( _T("CXmlNode::_GetValue 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
return FALSE;
}

return SUCCEEDED(hr);
}

//-------------------------------------------------------------------------
// Function Name :_SetValue
// Parameter(s) :CString & strValue IN
// Return :BOOL是否成功
// Memo :获取当前节点的值
//-------------------------------------------------------------------------
BOOL CXmlNode:: _SetValue(CString & strValue IN)
{
ASSERT( m_pNode != NULL );

HRESULT hr = S_OK;

try
{
if( HasChildren() )
{
// 下面有子结点
ASSERT( FALSE );
return FALSE;
}

hr = m_pNode->put_text( CComBSTR(strValue) );
ASSERT( SUCCEEDED(hr) );
}
catch ( _com_error e )
{
TRACE( _T("CXmlNode::_SetValue 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
return FALSE;
}
return SUCCEEDED(hr);
}

//-------------------------------------------------------------------------
// Function Name :_GetAttribute
// Parameter(s) :CString & strNameIN属性名
// Return:CString & strValue OUT属性值
// Memo :获取属性值
//-------------------------------------------------------------------------
BOOL CXmlNode::_GetAttribute( CString & strName IN, CString & strValue OUT)
{
ASSERT( m_pNode != NULL );

HRESULT hr = S_OK;

try
{
MSXML2::IXMLDOMNamedNodeMapPtr pIXMLDOMNamedNodeMap = NULL;
hr = m_pNode->get_attributes(&pIXMLDOMNamedNodeMap);
if( !SUCCEEDED(hr) )
{
ASSERT( FALSE );
return FALSE;
}

MSXML2::IXMLDOMNodePtr pIXMLDOMNode = NULL;
pIXMLDOMNode = pIXMLDOMNamedNodeMap->getNamedItem( _bstr_t(strName) );

if( pIXMLDOMNode == NULL )
{
strValue.Empty();
}
else
{
VARIANT varValue;
hr = pIXMLDOMNode->get_nodeValue(&varValue);
if( !SUCCEEDED(hr) )
{
ASSERT( FALSE );
return FALSE;
}

strValue = (LPCTSTR)(_bstr_t)varValue;
}

RELEASE_PTR(pIXMLDOMNode);
RELEASE_PTR(pIXMLDOMNamedNodeMap);
}
catch ( _com_error e )
{
TRACE( _T("CXmlNode::_GetAttribute 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
return FALSE;
}

return TRUE;
}


//-------------------------------------------------------------------------
// Function Name :_SetAttribute
// Parameter(s) :CString & strNameIN名称
//:CString & strValue IN 属性值
// Return :BOOL
// Memo :设置属性值
//-------------------------------------------------------------------------
BOOL CXmlNode::_SetAttribute( CString & strName, CString & strValue IN)
{
ASSERT( m_pNode != NULL );

HRESULT hr = S_OK;
try
{
MSXML2::IXMLDOMElementPtr pElement = NULL;
pElement = static_cast<:ixmldomelementptr> (m_pNode);<br>hr = pElement-&gt;setAttribute( (_bstr_t)CComBSTR(strName), _variant_t((LPCTSTR)strValue) );<br>RELEASE_PTR(pElement);<br>}<br>catch ( _com_error e )<br>{<br>TRACE( _T("CXmlNode::_SetAttribute 发生异常:%s/n"), e.ErrorMessage());<br>ASSERT( FALSE );<br>return FALSE;<br>}</:ixmldomelementptr>

return SUCCEEDED(hr);
}

//-------------------------------------------------------------------------
// Function Name :CXmlNode
// Parameter(s) :MSXML2::IXMLDOMNodePtr pNode[in]
// Memo :构造器
//-------------------------------------------------------------------------
CXmlNode::CXmlNode( MSXML2::IXMLDOMNodePtr pNode IN)
{
m_pNode = pNode;
}


//-------------------------------------------------------------------------
// Function Name :CXmlNode
// Parameter(s) :void
// Memo :构造器
//-------------------------------------------------------------------------
CXmlNode::CXmlNode(void)
{
m_pNode = NULL;
}


//-------------------------------------------------------------------------
// Function Name :CXmlNode
// Parameter(s) :CXmlNode & refNode [in]
// Memo :拷贝构造函数
//-------------------------------------------------------------------------
CXmlNode::CXmlNode( CXmlNode & refNode IN)
{
m_pNode = refNode.m_pNode;
}


//-------------------------------------------------------------------------
// Function Name :~CXmlNode
// Parameter(s) :void
// Memo :析构函数
//-------------------------------------------------------------------------
CXmlNode::~CXmlNode(void)
{
RELEASE_PTR(m_pNode);
}


//-------------------------------------------------------------------------
// Function Name :Release
// Parameter(s) :void
// Return :void
// Memo :释放节点
//-------------------------------------------------------------------------
void CXmlNode::Release(void)
{
RELEASE_PTR(m_pNode);
}


//-------------------------------------------------------------------------
// Function Name :operator =
// Parameter(s) :CXmlNodePtr pNode[in]
// Return :CXmlNodePtr
// Memo :重载 = 操作符
//-------------------------------------------------------------------------
CXmlNodePtr CXmlNode::operator = ( CXmlNodePtr pNode IN)
{
RELEASE_PTR(m_pNode);

m_pNode = pNode->m_pNode;
return pNode;
}


//-------------------------------------------------------------------------
// Function Name :operator =
// Parameter(s) :CXmlNode & refNode[in]
// Return :CXmlNode &
// Memo :重载 = 操作符
//-------------------------------------------------------------------------
CXmlNode & CXmlNode::operator = ( CXmlNode & refNode IN)
{
RELEASE_PTR(m_pNode);

m_pNode = refNode.m_pNode;
return (*this);
}


//-------------------------------------------------------------------------
// Function Name :IsNull
// Parameter(s) :void
// Return :BOOL
// Memo :判断此结点是否是空节点
//-------------------------------------------------------------------------
BOOL CXmlNode::IsNull(void)
{
return m_pNode == NULL;
}

//-------------------------------------------------------------------------
// Function Name :GetChild
// Parameter(s) :CString strName节点名称
//:BOOL bBuildIfNotExist不存在则创建?
// Return :儿子节点指针
// Memo :获取儿子
//-------------------------------------------------------------------------
CXmlNodePtr CXmlNode::GetChild( CString strName, BOOL bBuildIfNotExist /* = TRUE */)
{
ASSERT( m_pNode != NULL );

CXmlNodePtr pChild( new CXmlNode() );

try
{
MSXML2::IXMLDOMNodePtr pChildNode = NULL;
pChildNode = m_pNode->selectSingleNode(_bstr_t((LPCTSTR)strName));

// 不存在 则 创建
if( pChildNode == NULL && bBuildIfNotExist )
{
MSXML2::IXMLDOMDocumentPtr pDoc = NULL;
HRESULT hr = m_pNode->get_ownerDocument(&pDoc);
ASSERT( SUCCEEDED(hr) );

pChildNode = pDoc->createElement( _bstr_t(strName) );
ASSERT( pChildNode != NULL );

m_pNode->appendChild(pChildNode);

RELEASE_PTR(pDoc);
}

pChild->m_pNode = pChildNode;
RELEASE_PTR(pChildNode);
}
catch ( _com_error e )
{
TRACE( _T("CXmlNode::GetChild发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
}

return pChild;
}


//-------------------------------------------------------------------------
// Function Name :NewChild
// Parameter(s) :CString strName结点名称
// Return :CXmlNodePtr
// Memo :新增一个子结点
//-------------------------------------------------------------------------
CXmlNodePtr CXmlNode::NewChild( CString strName )
{
ASSERT( m_pNode != NULL );

CXmlNodePtr pChild( new CXmlNode() );

try
{
MSXML2::IXMLDOMDocumentPtr pDoc = NULL;
HRESULT hr = m_pNode->get_ownerDocument(&pDoc);
ASSERT( SUCCEEDED(hr) );

MSXML2::IXMLDOMNodePtr pChildNode = NULL;
pChildNode = pDoc->createElement( _bstr_t(strName) );
ASSERT( pChildNode != NULL );
RELEASE_PTR(pDoc);

m_pNode->appendChild(pChildNode);
pChild->m_pNode = pChildNode;
RELEASE_PTR(pChildNode);
}
catch ( _com_error e )
{
TRACE( _T("CXmlNode::NewChild 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
}
return pChild;
}


//-------------------------------------------------------------------------
// Function Name :AddChild
// Parameter(s) :CXmlNodePtr & pChildNode
// Return :void
// Memo :添加子结点
//-------------------------------------------------------------------------
void CXmlNode::AddChild( CXmlNodePtr & pChildNode)
{
ASSERT( m_pNode != NULL );

try
{
m_pNode->appendChild( pChildNode->m_pNode );
}
catch ( _com_error e )
{
TRACE( _T("CXmlNode::AddChild 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
}
}


//-------------------------------------------------------------------------
// Function Name :AddChild
// Parameter(s) :CXmlNode & refChildNode
// Return :void
// Memo :添加子结点
//-------------------------------------------------------------------------
void CXmlNode::AddChild( CXmlNode & refChildNode)
{
ASSERT( m_pNode != NULL );

try
{
m_pNode->appendChild( refChildNode.m_pNode );
}
catch ( _com_error e )
{
TRACE( _T("CXmlNode::AddChild 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
}
}


//-------------------------------------------------------------------------
// Function Name :GetParent
// Parameter(s) :void
// Return :CXmlNodePtr
// Memo :获取父结点
//-------------------------------------------------------------------------
CXmlNodePtr CXmlNode::GetParent(void)
{
ASSERT( m_pNode != NULL );

CXmlNodePtr pParent( new CXmlNode() );

try
{
pParent->m_pNode = m_pNode->GetparentNode();
}
catch ( _com_error e )
{
TRACE( _T("CXmlNode::GetParent 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
}
return pParent;
}


//-------------------------------------------------------------------------
// Function Name :GetName
// Parameter(s) :void
// Return :CString
// Memo :获取当前节点名称
//-------------------------------------------------------------------------
CString CXmlNode::GetName(void)
{
ASSERT( m_pNode != NULL );

CString strRet;

try
{
BSTR bstr = NULL;
HRESULT hr = m_pNode->get_nodeName(&bstr);
ASSERT( SUCCEEDED(hr) );
strRet = (LPCTSTR)_bstr_t( bstr, true);

if( bstr != NULL )
{
SysFreeString(bstr);
bstr = NULL;
}
}
catch ( _com_error e )
{
TRACE( _T("CXmlNode::GetName 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
}

return strRet;
}


//-------------------------------------------------------------------------
// Function Name :RemoveAttribute
// Parameter(s) :CString strName IN 属性名称
// Return :BOOL
// Memo :删除属性
//-------------------------------------------------------------------------
BOOL CXmlNode::RemoveAttribute( CString strName IN )
{
ASSERT( m_pNode != NULL );

HRESULT hr = S_OK;

try
{
MSXML2::IXMLDOMNamedNodeMapPtr pIXMLDOMNamedNodeMap = NULL;
hr = m_pNode->get_attributes(&pIXMLDOMNamedNodeMap);
ASSERT( SUCCEEDED(hr) );

if( SUCCEEDED(hr) )
pIXMLDOMNamedNodeMap->removeNamedItem( _bstr_t(strName) );
ASSERT( SUCCEEDED(hr) );

RELEASE_PTR(pIXMLDOMNamedNodeMap);
}
catch ( _com_error e )
{
TRACE( _T("CXmlNode::RemoveAttribute 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
return FALSE;
}


return SUCCEEDED(hr);
}

//-------------------------------------------------------------------------
// Function Name :HasChildren
// Parameter(s) :void
// Return :BOOL
// Memo :是否有子结点
//-------------------------------------------------------------------------
BOOL CXmlNode::HasChildren(void)
{
ASSERT( m_pNode != NULL );

BOOL bHasChildren = FALSE;
try
{
MSXML2::IXMLDOMNodeListPtr pNodeList = NULL;
pNodeList =m_pNode->selectNodes( _bstr_t("child::*") );
ASSERT( pNodeList != NULL );

bHasChildren = static_cast<bool> (pNodeList-&gt;length != 0);<br>RELEASE_PTR(pNodeList);<br>}<br>catch ( _com_error e )<br>{<br>TRACE( _T("CXmlNode::HasChildren 发生异常:%s/n"), e.ErrorMessage());<br>ASSERT( FALSE );<br>}<br>return bHasChildren;<br>}</bool>

//-------------------------------------------------------------------------
// Function Name :Remove
// Parameter(s) :
// Return :
// Memo :将此结点与父结点分离
//-------------------------------------------------------------------------
CXmlNode & CXmlNode::Remove(void)
{
ASSERT( m_pNode != NULL );

try
{
HRESULT hr = S_OK;
MSXML2::IXMLDOMNodePtr pNode = NULL;
hr = m_pNode->get_parentNode(&pNode);
ASSERT( SUCCEEDED(hr) );

pNode->removeChild(m_pNode);
}
catch ( _com_error e )
{
TRACE( _T("CXmlNode::Remove 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
}
return (*this);
}

//-------------------------------------------------------------------------
// Function Name :RemoveChildren
// Parameter(s) :
// Return :BOOL
// Memo :删除子结点
//-------------------------------------------------------------------------
BOOL CXmlNode::RemoveChildren(void)
{
ASSERT( m_pNode != NULL );

try
{
MSXML2::IXMLDOMNodeListPtr pNodeList = NULL;
pNodeList =m_pNode->selectNodes( _bstr_t("child::*") );

for( int i = 0; i length; i++)
{
m_pNode->removeChild( pNodeList->item[i] );
}

RELEASE_PTR(pNodeList);
}
catch ( _com_error e )
{
TRACE( _T("CXmlNode::Remove 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
return FALSE;
}

return TRUE;
}


//-------------------------------------------------------------------------
// Function Name :GetChildren
// Parameter(s) :void
// Return :CXmlNodesPtr
// Memo :获取子结点
//-------------------------------------------------------------------------
CXmlNodesPtr CXmlNode::GetChildren()
{
ASSERT( m_pNode != NULL );

CXmlNodesPtr pNodes ( new CXmlNodes() );
try
{
MSXML2::IXMLDOMNodeListPtr pNodeList = NULL;
pNodeList =m_pNode->selectNodes( _bstr_t("child::*") );

pNodes->m_pNodeList = pNodeList;
RELEASE_PTR(pNodeList);
}
catch ( _com_error e )
{
TRACE( _T("CXmlNode::GetChildren 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
}
return pNodes;
}


//-------------------------------------------------------------------------
// Function Name :SelectSingleNode
// Parameter(s) :LPCTSTR lpszPath路径
// Return :CXmlNodePtr
// Memo :选择单个结点
//-------------------------------------------------------------------------
CXmlNodePtr CXmlNode::SelectSingleNode(LPCTSTR lpszPath)
{
ASSERT( m_pNode != NULL );

CXmlNodePtr pNode ( new CXmlNode() );

try
{
MSXML2::IXMLDOMNodePtr pItem = NULL;
pItem = m_pNode->selectSingleNode( _bstr_t(lpszPath) );

pNode->m_pNode = pItem;
RELEASE_PTR(pItem);
}
catch ( _com_error e )
{
TRACE( _T("CXmlNode::SelectSingleNode 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
}

return pNode;
}

//-------------------------------------------------------------------------
// Function Name :SelectNodes
// Parameter(s) :LPCTSTR lpszPath路径
// Return :CXmlNodesPtr
// Memo :选择结点集合
//-------------------------------------------------------------------------
CXmlNodesPtr CXmlNode::SelectNodes(LPCTSTR lpszPath)
{
ASSERT( m_pNode != NULL );

CXmlNodesPtr pNodes ( new CXmlNodes() );
try
{
MSXML2::IXMLDOMNodeListPtr pNodeList = NULL;
pNodeList =m_pNode->selectNodes( _bstr_t(lpszPath) );

pNodes->m_pNodeList = pNodeList;
RELEASE_PTR(pNodeList);
}
catch ( _com_error e )
{
TRACE( _T("CXmlNode::SelectNodes 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
}

return pNodes;
}


//////////////////////////////////////////////////////////////////////////
// 下列为取值的重载方法

// 取值重载版本
CString CXmlNode::GetValue(LPCTSTR lpszValue /* = NULL */ )
{
CString strValue;
_GetValue(strValue);

if( strValue.IsEmpty() &&
lpszValue != NULL )
{
strValue = lpszValue;
_SetValue(strValue);
}

return strValue;
}

// 取值重载版本
bool CXmlNode::GetValue( bool bDefault )
{
CString strValue;
_GetValue(strValue);

if( strValue.CompareNoCase(_T("1")) == 0 )
{
return TRUE;
}
else if( strValue.CompareNoCase(_T("0")) == 0 )
{
return FALSE;
}
else
{
strValue = bDefault ? "1" : "0";
_SetValue(strValue);
return bDefault;
}
}

// 取值重载版本
int CXmlNode::GetValue( int nDefault )
{
CString strValue;
_GetValue(strValue);

if( strValue.IsEmpty() )
{
strValue.Format( _T("%d"), nDefault);
_SetValue(strValue);
}

return _ttoi(strValue);
}

// 取值重载版本
float CXmlNode::GetValue( float fDefault )
{
CString strValue;
_GetValue(strValue);

if( strValue.IsEmpty() )
{
strValue.Format( _T("%f"), fDefault);
_SetValue(strValue);
}

return static_cast <float> (_tstof(strValue));<br>}</float>

// 取值重载版本
double CXmlNode::GetValue( double dDefault )
{
CString strValue;
_GetValue(strValue);

if( strValue.IsEmpty() )
{
strValue.Format( _T("%.12f"), dDefault);
_SetValue(strValue);
}

return _tstof(strValue);
}


//////////////////////////////////////////////////////////////////////////
// 下列为赋值的重载方法

// 赋值重载版本
BOOL CXmlNode::SetValue( LPCTSTR lpszValue )
{
CString strValue(lpszValue);
return _SetValue(strValue);
}

// 赋值重载版本
BOOL CXmlNode::SetValue( bool bValue )
{
CString strValue;
strValue = bValue ? _T("1") : _T("0");

return _SetValue(strValue);
}

// 赋值重载版本
BOOL CXmlNode::SetValue( int nValue )
{
CString strValue;
strValue.Format( _T("%d"), nValue);

return _SetValue(strValue);
}

// 赋值重载版本
BOOL CXmlNode::SetValue( float fValue )
{
CString strValue;
strValue.Format( _T("%f"), fValue);

return _SetValue(strValue);
}

// 赋值重载版本
BOOL CXmlNode::SetValue( double dValue )
{
CString strValue;
strValue.Format( _T("%.12f"), dValue);

return _SetValue(strValue);
}

//////////////////////////////////////////////////////////////////////////
// 下面是获取属性的函数

// 属性取值重载版本
CString CXmlNode::GetAttribute( CString strName, LPCTSTR lpszDefault /* = NULL */)
{
CString strValue;
_GetAttribute( strName, strValue);

if( strValue.IsEmpty() &&
lpszDefault != NULL )
{
strValue = lpszDefault;
_SetAttribute( strName, strValue);
}
return strValue;
}

// 属性取值重载版本
bool CXmlNode::GetAttribute( CString strName, bool bDefault)
{
CString strValue;
_GetAttribute( strName, strValue);

if( strValue.CompareNoCase(_T("1")) == 0 )
{
return TRUE;
}
else if( strValue.CompareNoCase(_T("0")) == 0 )
{
return FALSE;
}
else
{
strValue = bDefault ? _T("1") : _T("0");
_SetAttribute( strName, strValue);
return bDefault;
}
}

// 属性取值重载版本
intCXmlNode::GetAttribute( CString strName, int nDefault)
{
CString strValue;
_GetAttribute( strName, strValue);

if( strValue.IsEmpty() )
{
strValue.Format( _T("%d"), nDefault);
_SetAttribute( strName, strValue);
}

return _ttoi(strValue);
}

// 属性取值重载版本
float CXmlNode::GetAttribute( CString strName, float fDefault)
{
CString strValue;
_GetAttribute( strName, strValue);

if( strValue.IsEmpty() )
{
strValue.Format( _T("%f"), fDefault);
_SetAttribute( strName, strValue);
}

return static_cast <float> (_tstof(strValue));<br>}</float>

// 属性取值重载版本
double CXmlNode::GetAttribute( CString strName, double dDefault)
{
CString strValue;
_GetAttribute( strName, strValue);

if( strValue.IsEmpty() )
{
strValue.Format( _T("%.12f"), dDefault);
_SetAttribute( strName, strValue);
}

return _tstof(strValue);
}


//////////////////////////////////////////////////////////////////////////
// 下面是设置属性的函数

// 属性赋值重载版本
BOOL CXmlNode::SetAttribute( CString strName, LPCTSTR lpszValue)
{
CString strValue;
strValue = lpszValue;

return _SetAttribute( strName, strValue);
}

// 属性赋值重载版本
BOOL CXmlNode::SetAttribute( CString strName, bool bValue)
{
CString strValue;
strValue = bValue ? _T("1") : _T("0");

return _SetAttribute( strName, strValue);
}

// 属性赋值重载版本
BOOL CXmlNode::SetAttribute( CString strName, int nValue)
{
CString strValue;
strValue.Format( _T("%d"), nValue);

return _SetAttribute( strName, strValue);
}

// 属性赋值重载版本
BOOL CXmlNode::SetAttribute( CString strName, float fValue)
{
CString strValue;
strValue.Format( _T("%f"), fValue);

return _SetAttribute( strName, strValue);
}

// 属性赋值重载版本]
BOOL CXmlNode::SetAttribute( CString strName, double dValue)
{
CString strValue;
strValue.Format( _T("%.12f"), dValue);

return _SetAttribute( strName, strValue);
}

#pragma once


#include "./XmlNode.h"


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

public:
~CXmlNodes(void);
CXmlNodes(void);
CXmlNodes( CXmlNodes & refNodes );

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


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

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

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

};

#include "StdAfx.h"
#include "./xmlnodes.h"


// 下面是构造函数 和 析构函数
CXmlNodes::CXmlNodes(MSXML2::IXMLDOMNodeListPtr pNodeList)
{
m_pNodeList = pNodeList;
}

CXmlNodes::CXmlNodes( CXmlNodes & refNodes )
{
m_pNodeList = refNodes.m_pNodeList;
}

CXmlNodes::CXmlNodes(void)
: m_pNodeList(NULL)
{
}

CXmlNodes::~CXmlNodes(void)
{
Release();
}

//////////////////////////////////////////////////////////////////////////
void CXmlNodes::Release(void)
{
RELEASE_PTR(m_pNodeList);
}


//-------------------------------------------------------------------------
// Function Name :operator =
// Parameter(s) :CXmlNodesPtr pNodes
// Return :CXmlNodesPtr
// Memo :重载 = 号
//-------------------------------------------------------------------------
CXmlNodesPtr CXmlNodes::operator = ( CXmlNodesPtr pNodes IN )
{
RELEASE_PTR(m_pNodeList);

m_pNodeList = pNodes->m_pNodeList;
return pNodes;
}


//-------------------------------------------------------------------------
// Function Name :operator =
// Parameter(s) :CXmlNodes & refNodes
// Return :CXmlNodes &
// Memo :重载 = 号
//-------------------------------------------------------------------------
CXmlNodes & CXmlNodes::operator = (CXmlNodes & refNodes)
{
RELEASE_PTR(m_pNodeList);

m_pNodeList = refNodes.m_pNodeList;
return (*this);
}

//-------------------------------------------------------------------------
// Function Name :GetCount
// Parameter(s) :void
// Return :LONG
// Memo :获取数量
//-------------------------------------------------------------------------
LONG CXmlNodes::GetCount(void)
{
ASSERT( m_pNodeList != NULL );

try
{
return m_pNodeList->length;
}
catch ( _com_error e )
{
TRACE( _T("CXmlNodes::GetCount 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
return -1;
}
}

//-------------------------------------------------------------------------
// Function Name :GetItem
// Parameter(s) :LONG nIndex索引
// Return :CXmlNodePtr
// Memo :获取集合中的结点
//-------------------------------------------------------------------------
CXmlNodePtr CXmlNodes::GetItem( LONG nIndex )
{
ASSERT( m_pNodeList != NULL );
ASSERT( nIndex >= 0 && nIndex

CXmlNodePtr pNode ( new CXmlNode(m_pNodeList->item[nIndex]) );

return pNode;
}


//-------------------------------------------------------------------------
// Function Name :operator[]
// Parameter(s) :INT nIndex
// Return :CXmlNodePtr
// Memo :作用同 GetItem( LONG nIndex )
//-------------------------------------------------------------------------
CXmlNodePtr CXmlNodes::operator[] ( LONG lIndex )
{
return GetItem(lIndex);
}


//-------------------------------------------------------------------------
// Function Name :GetItem
// Parameter(s) :LPCTSTR lpszName结点名称
// Return :CXmlNodePtr
// Memo :根据名称在结点集中查结点
//-------------------------------------------------------------------------
CXmlNodePtr CXmlNodes::GetItem( LPCTSTR lpszName )
{
ASSERT( m_pNodeList != NULL );
ASSERT( lpszName != NULL );

CXmlNodePtr pNode ( new CXmlNode() );

try
{
HRESULT hr = S_OK;
CString strName;
BSTR bstr = NULL;
MSXML2::IXMLDOMNodePtr pItem = NULL;

for( int i = 0; i length; i++)
{
pItem = m_pNodeList->item[i];

hr = pItem->get_nodeName(&bstr);

strName = (LPCTSTR)_bstr_t( bstr, true);
if( bstr != NULL )
{
SysFreeString(bstr);
bstr = NULL;
}

// 查找第一个相等的
if( strName.Compare(lpszName) == 0 )
{
pNode->m_pNode = pItem;
RELEASE_PTR(pItem);
return pNode;
}

RELEASE_PTR(pItem);
}
}
catch ( _com_error e )
{
TRACE( _T("CXmlNodes::GetItem 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
}

return pNode;
}


//-------------------------------------------------------------------------
// Function Name :operator[]
// Parameter(s) :LPCTSTR lpszName结点名称
// Return :CXmlNodePtr
// Memo :作用同 GetItem( LPCTSTR lpszName )
//-------------------------------------------------------------------------
CXmlNodePtr CXmlNodes::operator[] ( LPCTSTR lpszName )
{
return GetItem(lpszName);
}





分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics