Resource.h文件
/*Resource.h*/
//{{NO_DEPENDENCIES}}
//Microsoft Visual C++ generated include file.
//Used by XMLParseInterface.RC
//新对象的下一组默认值
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 3000
#define _APS_NEXT_CONTROL_VALUE 3000
#define _APS_NEXT_SYMED_VALUE 3000
#define _APS_NEXT_COMMAND_VALUE 32771
#endif
#endif
XMLParseInterface.h文件
XMLPARSEINTERFACE_EXPORTS
#ifdef XMLPARSEINTERFACE_EXPORTS
#define XMLPARSEINTERFACE_API __declspec(dllexport)
#else
#define XMLPARSEINTERFACE_API __declspec(dllimport)
#endif
#include
#include
#include
#include
class XMLPARSEINTERFACE_API CXMLObject
{
public:
//!得到节点名字
/*!
* /return 返回该节点的名字
*/
CString GetNodeName() const;
//!得到节点深度
/*!
* /return 返回该节点的深度
*/
int GetLevel() const;
//!得到父节点对象
/*!
* /return 返回该节点的父节点对象
*/
CXMLObject * GetParent() const;
//!得到属性列表中指定索引的属性
/*!
* /param iIndex 指定的索引-输入参数
* /param szAttributeValue 属性-输出参数
* /return 如果找到则返回该TRUE,否则返回FALSE
*/
bool GetAttributeOnIndex( int iIndex , CString & szAttributeValue) const;
//!得到属性列表中属性的个数
/*!
* /return 返回属性个数
*/
int GetAttributeCount() const;
//!查找指定属性名称的属性值
/*!
* /param szAttributeName 指定的属性名称-输入参数
* /param szAttributeValue 属性-输出参数
* /return 如果找到则返回该TRUE,否则返回FALSE
*/
bool FindAttribute( const CString & szAttributeName, CString & szAttributeValue ) const;
//!查找指定索引处的子节点对象
/*!
* /param iIndex 指定的索引-输入参数
* /return 返回指定索引的孩子节点对象
*/
CXMLObject * GetChildOnIndex( int iIndex );
const CXMLObject * GetChildOnIndex( int iIndex )const;
//!得到孩子节点个数
/*!
* /return 返回孩子节点个数
*/
int GetChildrenCount() const;
//!祖先关系判断
/*!
* /param pParant 假设的祖先节点-输入参数
* /return 如果确实是该节点的祖先返回TRUE,否则返回FALSE
*/
bool IsPosterityOf( CXMLObject * pParant );
//!是否叶子
/*!
* /return 如果是叶子节点返回TRUE,否则返回FALSE
*/
bool IsLeaf() const;
private:
//友元类声明
friend class CXMLStructBuilder;
private:
//!构造函数
/*!
* /param szNmae 节点名字-输入参数
* /param iLevel 节点深度-输入参数
* /param pParant 节点的父节点-输入参数
*/
CXMLObject( const CString & szNmae, int iLevel , CXMLObject * pParant = NULL);
//!析构函数
~CXMLObject();
//!线索化
/*!
* /param io_pPre 线索指针-输入输出参数
* /return 如果成功返回TRUE,否则返回FALSE
*/
bool Threaded_Preorder( CXMLObject ** & io_pPre );
//!加入属性
/*!
* /param szAttributeName 属性名字-输入参数
* /param szAttributeValue 属性值-输入参数
* /return void
*/
void AddAttribute( const CString & szAttributeName, const CString & szAttributeValue );
//!加入孩子节点
/*!
* /param pChild 要加入的孩子节点-输入参数
* /return void
*/
void AddChild( CXMLObject * pChild );
//!销毁所有孩子节点
/*!
* /return void
*/
void DestroyChildren();
private:
/*线索化指针*/
CXMLObject * m_pThreaded_Preorder;
/*节点名字*/
CString m_szName;
/*保存此节点深度*/
int m_iLevel;
/*保存父亲节点指针*/
CXMLObject * m_pParent;
/*孩子节点链表*/
CArray< CXMLObject *, CXMLObject * > m_aChildren;
/*为了安顺序查找属性*/
CArray< CString ,CString > m_strAttr;
/*属性表*/
CMapStringToString m_AttrMap;
};
class XMLPARSEINTERFACE_API CXMLStructBuilder
{
public:
//!构造函数
/*!
* /param pszLocalAddr 本地绑定地址
* /param uLocalPort 本地绑定端口
* /return 如果创建成功返回true,否则返回false
*/
CXMLStructBuilder();
//!建立结构树
/*!
* /param szPath XML文件的路径-输入参数
* /param pRoot 根元素节点对象-输出参数
* /return 如果创建成功返回true,否则返回false
*/
bool BuildTree( const CString & szPath , CXMLObject * &pRoot );
//!查找命名节点对象
/*!
* /param szName 节点名称-输入参数
* /param pStartNode 指定开始查找的位置-输入参数
* /return 如果找到则返回该对象,否则返回NULL
*/
CXMLObject * FindNamedNode( const CString & szName , CXMLObject * pStartNode );
//!查找命名子节点对象
/*!
* /param szName 节点名称-输入参数
* /param pStartNode 指定开始查找的位置-输入参数
* /param pParant 父节点对象,找到的结果必须是pParant的子节点-输入参数
* /return 如果找到则返回该对象,否则返回NULL
*/
CXMLObject * FindNamedSubNode( const CString & szName ,CXMLObject * pStartNode , CXMLObject * pParant );
//!查找命名同级节点对象
/*!
* /param szName 节点名称-输入参数
* /param pStartNode 指定开始查找的位置-输入参数
* /param iLevel 指定的深度,找到的结果的节点深度必须为iLevel-输入参数
* /return 如果找到则返回该对象,否则返回NULL
*/
CXMLObject * FindNamedLevelNode( const CString & szName , CXMLObject * pStartNode ,int iLevel );
//!销毁结构树
void DestroyTree();
public:
//!析构函数
~CXMLStructBuilder();
private:
//!创建结构树节点对象
/*!
* /param pRoot IXMLDOMNode节点对象-输入参数
* /param iLevel 指定的深度-输入参数
* /param pParant 构造结果的父节点-输入参数
* /return 如果找到则返回该TRUE,否则返回FALSE
*/
bool BuildXMLObject( IXMLDOMNode * pRoot , int iLevel , CXMLObject * pParant );
//!创建结构树节点对象
/*!
* /param pNode IXMLDOMNode节点对象-输入参数
* /param pParant CXMLObject节点对象-输入参数
* /return 如果找到则返回该TRUE,否则返回FALSE
*/
bool BuildAttribute( IXMLDOMNode * pNode , CXMLObject * pParant );
private:
/*根节点对象*/
CXMLObject * m_pXmlTreeRoot;//=NULL;
};
XMLParseInterface.cpp文件
#include "stdafx.h"
#include
#include "XMLParseInterface.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
static AFX_EXTENSION_MODULE XMLParseInterfaceDLL = { NULL, NULL };
#ifdef _MANAGED
#pragma managed(push, off)
#endif
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
// 如果使用 lpReserved,请将此移除
UNREFERENCED_PARAMETER(lpReserved);
if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("XMLParseInterface.DLL 正在初始化!/n");
// 扩展 DLL 一次性初始化
if (!AfxInitExtensionModule(XMLParseInterfaceDLL, hInstance))
return 0;
// 将此 DLL 插入到资源链中
// 注意: 如果此扩展 DLL 由
// MFC 规则 DLL (如 ActiveX 控件)隐式链接到,
// 而不是由 MFC 应用程序链接到,则需要
// 将此行从 DllMain 中移除并将其放置在一个
// 从此扩展 DLL 导出的单独的函数中。使用此扩展 DLL 的
// 规则 DLL 然后应显式
// 调用该函数以初始化此扩展 DLL。否则,
// CDynLinkLibrary 对象不会附加到
// 规则 DLL 的资源链,并将导致严重的
// 问题。
new CDynLinkLibrary(XMLParseInterfaceDLL);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("XMLParseInterface.DLL 正在终止!/n");
// 在调用析构函数之前终止该库
AfxTermExtensionModule(XMLParseInterfaceDLL);
}
return 1; // 确定
}
#ifdef _MANAGED
#pragma managed(pop)
#endif
CXMLObject::CXMLObject( const CString & szNmae, int iLevel, CXMLObject * pParant )
{
m_szName = szNmae;
m_iLevel = iLevel;
m_pParent = pParant;
}
CXMLObject::~CXMLObject()
{
DestroyChildren();
}
void CXMLObject::AddAttribute( const CString & szAttributeName, const CString & szAttributeValue )
{
m_AttrMap.SetAt( szAttributeName , szAttributeValue );
m_strAttr.Add( szAttributeName );
}
void CXMLObject::AddChild( CXMLObject * pChild )
{
m_aChildren.Add( pChild );
}
bool CXMLObject::FindAttribute( const CString & szAttributeName , CString & szAttributeValue ) const
{
if( m_AttrMap.Lookup( szAttributeName , szAttributeValue ) )
return true;
return false;
}
CString CXMLObject::GetNodeName() const
{
return m_szName;
}
int CXMLObject::GetLevel() const
{
return m_iLevel;
}
CXMLObject * CXMLObject::GetParent() const
{
if ( m_iLevel == 0 )
{
return NULL;
}
return m_pParent;
}
bool CXMLObject::GetAttributeOnIndex( int iIndex, CString & szAttributeValue ) const
{
int iSize = GetAttributeCount();
for (int i = 0; i < iSize; i++ )
{
if( i == iIndex )
{
this -> FindAttribute ( m_strAttr.ElementAt( i ) , szAttributeValue );
return true;
}
}
return false;
}
int CXMLObject::GetAttributeCount() const
{
return m_AttrMap.GetSize();
}
bool CXMLObject::IsLeaf() const
{
if( m_aChildren.IsEmpty() )
return true;
return false;
}
CXMLObject * CXMLObject::GetChildOnIndex( int iIndex )
{
CXMLObject * pChild = NULL;
pChild = m_aChildren.ElementAt( iIndex );
if( pChild != NULL )
return pChild;
return NULL;
}
const CXMLObject * CXMLObject::GetChildOnIndex( int iIndex ) const
{
CXMLObject * pChildI = NULL;
pChildI = m_aChildren.ElementAt( iIndex );
if( pChildI != NULL )
return pChildI;
return NULL;
}
int CXMLObject::GetChildrenCount() const
{
return m_aChildren.GetSize();
}
void CXMLObject::DestroyChildren()
{
for(int i = 0;i < m_aChildren.GetSize(); i++ )
delete m_aChildren.ElementAt( i );
m_aChildren.RemoveAll();
}
bool CXMLObject::IsPosterityOf( CXMLObject * pParant )
{
CXMLObject * pAncestor = this -> m_pParent;
do
{
if ( pAncestor == pParant )
{
return true;
}
pAncestor = pAncestor -> m_pParent;
}while( pAncestor );
return false;
}
bool CXMLObject::Threaded_Preorder( CXMLObject ** & io_pPre )
{
if( !io_pPre )
{
return false;
}
m_pThreaded_Preorder = NULL; //!清空,防止重复调用线性化算法时发生错误
( *io_pPre ) = this;
io_pPre = &m_pThreaded_Preorder;
int iArrayCount=GetChildrenCount();
for( int i = 0;i < iArrayCount; i++ )
{
if( !( m_aChildren.ElementAt( i) -> Threaded_Preorder( io_pPre ) ) )
{
return false;
}
}
return true;
}
////////////////////////////////////////////////////////////
CXMLStructBuilder::CXMLStructBuilder()
{
m_pXmlTreeRoot=NULL;
}
CXMLStructBuilder::~CXMLStructBuilder()
{
delete m_pXmlTreeRoot;
}
bool CXMLStructBuilder::BuildTree( const CString & szPath , CXMLObject * & pRoot )
{
bool bSucc = false;
try
{
if( m_pXmlTreeRoot != NULL )
DestroyTree();
HRESULT hr;
if( !szPath.IsEmpty() )
{
if( SUCCEEDED( CoInitialize( NULL ) ) )
{
IXMLDOMDocument * pDoc = NULL;
hr = CoCreateInstance( CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument,( void ** )( &pDoc ) );
if( SUCCEEDED( hr ) )
{
if( SUCCEEDED( pDoc -> put_async( VARIANT_FALSE ) ) )
{
CComVariant cvFileName( szPath );
VARIANT_BOOL vBool;
hr = pDoc -> load( cvFileName, &vBool );
if( vBool == VARIANT_TRUE )
{
IXMLDOMNode * pXMLRootNode = NULL;
if( SUCCEEDED( pDoc -> QueryInterface( IID_IXMLDOMNode, reinterpret_cast< void** >( &pXMLRootNode ) ) ) )
{
BSTR bstr;
if( FAILED( pXMLRootNode->get_nodeName( &bstr ) ) )
{
return false;
}
CString cstr;
cstr = bstr;
SysFreeString( bstr );
m_pXmlTreeRoot = new CXMLObject( cstr,0 );
pRoot = m_pXmlTreeRoot;
BuildXMLObject( pXMLRootNode , 1 , m_pXmlTreeRoot );
CXMLObject ** pre = &m_pXmlTreeRoot;
m_pXmlTreeRoot -> Threaded_Preorder( pre );
pXMLRootNode -> Release();
pXMLRootNode = NULL;
bSucc = true;
}
}
}
pDoc -> Release();
pDoc = NULL;
}
CoUninitialize();
}
}
}
catch( ... )
{
return false;
}
return bSucc;
}
void CXMLStructBuilder::DestroyTree()
{
if( m_pXmlTreeRoot != NULL )
{
delete m_pXmlTreeRoot;
m_pXmlTreeRoot = NULL;
}
}
bool CXMLStructBuilder::BuildXMLObject( IXMLDOMNode * pRoot , int iLevel , CXMLObject * pParant )
{
try
{
if( !pRoot )
{
return false;
}
DOMNodeType NodeType;
if( FAILED( pRoot -> get_nodeType( &NodeType ) ) )
{
return false;
}
switch( NodeType )
{
case NODE_COMMENT:
return true;
default:
break;
}
BSTR bstr;
if( FAILED( pRoot -> get_nodeName( &bstr ) ) )
{
return false;
}
CString cstr( bstr );
SysFreeString( bstr );
CXMLObject * pChildNode = NULL;
pChildNode = new CXMLObject( cstr,iLevel,pParant );
if( !pChildNode )
{
return false;
}
pParant -> AddChild( pChildNode );
BuildAttribute( pRoot, pChildNode );
IXMLDOMNodeList * pXMLChildNodeList = NULL;
if( FAILED( pRoot -> get_childNodes( &pXMLChildNodeList ) ) )
{
return false;
}
IXMLDOMNode * pXMLChildNode = NULL;
long lNodeCount = 0;
pXMLChildNodeList -> get_length( &lNodeCount );
for( long j = 0; j < lNodeCount; ++j )
{
if( FAILED( pXMLChildNodeList->get_item( j, &pXMLChildNode ) ) )
{
pXMLChildNodeList -> Release();
pXMLChildNodeList = NULL;
return false;
}
if( !BuildXMLObject( pXMLChildNode,iLevel+1, pChildNode ) )
{
pXMLChildNode -> Release();
pXMLChildNode = NULL;
pXMLChildNodeList -> Release();
pXMLChildNodeList = NULL;
return false;
}
pXMLChildNode -> Release();
pXMLChildNode = NULL;
}
pXMLChildNodeList -> Release();
pXMLChildNodeList = NULL;
}
catch( ... )
{
return false;
}
return true;
}
bool CXMLStructBuilder::BuildAttribute( IXMLDOMNode * pNode , CXMLObject * pThis )
{
try
{
IXMLDOMNamedNodeMap * pXMLNodeMap = NULL;
if( FAILED( pNode -> get_attributes( &pXMLNodeMap ) ) )
{
return false;
}
if( pXMLNodeMap )
{
IXMLDOMNode * pXMLAttributeNode = NULL;
long lAttributeCount = 0;
pXMLNodeMap -> get_length( &lAttributeCount );
for( long i = 0; i < lAttributeCount; ++i )
{
if( FAILED( pXMLNodeMap -> nextNode( &pXMLAttributeNode ) ) )
{
pXMLNodeMap -> Release();
pXMLNodeMap = NULL;
return false;
}
BSTR bstrName;
CString cstrName;
if( FAILED( pXMLAttributeNode -> get_nodeName( &bstrName ) ) )
{
pXMLAttributeNode -> Release();
pXMLAttributeNode = NULL;
pXMLNodeMap -> Release();
pXMLNodeMap = NULL;
return false;
}
cstrName = bstrName;
SysFreeString( bstrName );
VARIANT vstrValue;
if( FAILED( pXMLAttributeNode -> get_nodeValue( &vstrValue ) ) )
{
pXMLAttributeNode -> Release();
pXMLAttributeNode = NULL;
pXMLNodeMap -> Release();
pXMLNodeMap = NULL;
return false;
}
CString cstrValue;
cstrValue = vstrValue;
VariantClear( &vstrValue );
pThis -> AddAttribute( cstrName, cstrValue );
pXMLAttributeNode -> Release();
pXMLAttributeNode = NULL;
}
pXMLNodeMap -> Release();
pXMLNodeMap = NULL;
}
}
catch( ... )
{
return false;
}
return true;
}
CXMLObject* CXMLStructBuilder::FindNamedNode( const CString & szNodeName,CXMLObject * pStartNode )
{
CXMLObject * pRoot = pStartNode;
pRoot = pRoot -> m_pThreaded_Preorder;
while ( pRoot != NULL )
{
if ( pRoot -> GetNodeName().Compare( szNodeName ) == 0 )
{
return pRoot;
}
pRoot = pRoot -> m_pThreaded_Preorder;
}
return NULL;
}
CXMLObject * CXMLStructBuilder::FindNamedSubNode( const CString & szName,CXMLObject * pStartNode,CXMLObject * pParant )
{
CXMLObject * pRoot = pStartNode;
pRoot = pRoot -> m_pThreaded_Preorder;
while ( pRoot != NULL )
{
if( pRoot -> GetLevel() <= pParant -> GetLevel() )
break;
if ( ( pRoot -> GetNodeName().Compare( szName ) == 0) && ( pRoot -> IsPosterityOf( pParant ) ) )
{
return pRoot;
}
pRoot = pRoot -> m_pThreaded_Preorder;
}
return NULL;
}
CXMLObject * CXMLStructBuilder::FindNamedLevelNode( const CString & szName ,CXMLObject * pStartNode,int iLevel )
{
CXMLObject * pRoot = pStartNode;
pRoot = pRoot -> m_pThreaded_Preorder;
while (pRoot != NULL)
{
if((pRoot -> GetLevel() == iLevel ) && ( pRoot -> GetNodeName().Compare( szName )==0 ) )
{
return pRoot;
}
pRoot = pRoot -> m_pThreaded_Preorder;
}
return NULL;
}