#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;
CString m_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 strIn Base64编码
// :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
#include
#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
CXmlNodePtr;
typedef std::auto_ptr
CXmlNodesPtr;
//
#include "./XmlNodes.h"
class CXmlNode
{
friend class CXml;
friend class CXmlNode;
friend class CXmlNodes;
protected:
MSXML2::IXMLDOMNodePtr m_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);
// _______________
//______| 属性操作 |___________________________________________________________________
CString GetAttribute( CString strName, LPCTSTR lpszDefault = NULL);
bool GetAttribute( CString strName, bool bDefault);
int GetAttribute( CString strName, int nDefault);
float GetAttribute( CString strName, float fDefault);
double GetAttribute( CString strName, double dDefault);
BOOL SetAttribute( CString strName, LPCTSTR lpszValue);
BOOL SetAttribute( CString strName, bool bValue);
BOOL SetAttribute( CString strName, int nValue);
BOOL SetAttribute( CString strName, float fValue);
BOOL SetAttribute( CString strName, double dValue);
BOOL RemoveAttribute( CString strName );
// _______________
//______| 值操作 |___________________________________________________________________
CString GetValue( LPCTSTR lpszDefault = NULL );
bool GetValue( bool bDefault );
int GetValue( int nDefault);
float GetValue( float fDefault);
double GetValue( double dDefault);
BOOL SetValue( LPCTSTR lpszValue );
BOOL SetValue( bool bValue );
BOOL SetValue( int nValue );
BOOL SetValue( float fValue );
BOOL SetValue( 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 & strName IN 属性名
// 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 & strName IN 名称
// :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
(m_pNode);
hr = pElement->setAttribute( (_bstr_t)CComBSTR(strName), _variant_t((LPCTSTR)strValue) );
RELEASE_PTR(pElement);
}
catch ( _com_error e )
{
TRACE( _T("CXmlNode::_SetAttribute 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
return FALSE;
}
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
(pNodeList->length != 0);
RELEASE_PTR(pNodeList);
}
catch ( _com_error e )
{
TRACE( _T("CXmlNode::HasChildren 发生异常:%s/n"), e.ErrorMessage());
ASSERT( FALSE );
}
return bHasChildren;
}
//-------------------------------------------------------------------------
// 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 < pNodeList->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
(_tstof(strValue));
}
// 取值重载版本
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;
}
}
// 属性取值重载版本
int CXmlNode::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
(_tstof(strValue));
}
// 属性取值重载版本
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 < GetCount() );
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 < m_pNodeList->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);
}