XML解析器接口--C++版

本文介绍了一个用于解析XML文件的C++类库实现,包括XML结构的构建、节点操作及属性管理等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 <afxtempl.h></afxtempl.h>

#include <afxcoll.h></afxcoll.h>

#include <msxml.h></msxml.h>

#include <atlbase.h></atlbase.h>

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 m_aChildren;

/*为了安顺序查找属性*/

CArray 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 <afxdllx.h></afxdllx.h>

#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

{

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

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

{

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( &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

{

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

{

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() 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;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值