把dwg图纸中的点位信息导出xml文件

首先程序启动自动加载一张默认的dwg,然后注册导出命令

这里我放了一张测试用的dwg做数据:https://www.jianguoyun.com/p/DaZOQuAQ-pqcBhi7sTQ

这里是第一版本,后期又改进了一个版本:https://my.oschina.net/u/2930533/blog/1573584

acrxEntryPoint.cpp

//该函数会在程序启动后自动执行
virtual AcRx::AppRetCode On_kLoadDwgMsg(void * pkt)
{
	AcRx::AppRetCode retCode =AcRxArxApp::On_kLoadDwgMsg (pkt) ;
	CDwgDataToXml::OnLoadDWG();
		
	return (retCode) ;
}

static void HHCDwgPt2XmlApp(void)
{
        CDwgDataToXml::Inlet();
}

//注册命令
ACED_ARXCOMMAND_ENTRY_AUTO(CDwgPt2XmlApp, HH, CDwgPt2XmlApp, HHDCXML, ACRX_CMD_TRANSPARENT, NULL)

 具体实现:

DwgDataToXml.h

#pragma once
#include <vector>
#include "PrjStruct.h"

//把dwg中的点位数据整理成xml文件	
class CDwgDataToXml
{
public:
	CDwgDataToXml(void);
	~CDwgDataToXml(void);

public:
	//外部入口
	static void Inlet();
	//加载dwg图纸
	static void OnLoadDWG();

private:
	// 由选择集得到实体ID
	BOOL GetIdArrayFromSS(ads_name selectSet,AcDbObjectIdArray &idArray);
	//通过实体id获得坐标点
	bool GetPosFromId(const AcDbObjectId &polyId,AcGePoint3dArray &vecPoint);
	//得到离标注最近的点
	AcGePoint3d GetNearestPoint(const AcGePoint3d ptPoint,AcGePoint3dArray& vecXYPoint);
	//判断是否加入数据结构(包1,包2等不加入)
	bool IsAddArr(CPointInfoArr& arrPointData,CPointInfo& ptData,AcGePoint3d ptPoint,AcDbEntity* pEnt);

	//通过id得到桩位信息
	bool GetDataFromId(AcDbObjectId &Id,CPointInfo& ptData,AcGePoint3dArray& vecXYPoint,CPointInfoArr& arrPointData);
	//通过选择集得到桩位信息
	bool GetDataFromXZJ(resbuf* eb,CPointInfoArr& arrPointData,AcGePoint3dArray& vecXYPoint);
	//得到桩位XY坐标点
	bool GetXYPoints(resbuf* eb,AcGePoint3dArray &vecPoint);
	//写入xml文件
	bool WriteXml(CPointInfoArr& arrPointData);
	//得到最近的标注,并修改缓存中记录的
	bool ModifNearestLabel(CPointInfo& ptData);

	//得到上一级目录
	void GetParentPath(CString & strPath);
	//得到dwg图纸路径
	CString GetDwgPath();
	//打开dwg图纸
	BOOL OpenDwg(CString &strPath);

	// 获取用户选择的路径
	bool GetUserSelectDir(CString & strPath);

private:
	std::map<CString,AcGePoint3d> m_mapLable;//桩位名称的位置
};

DwgDataToXml.cpp

#include "StdAfx.h"
#import <MSXML.DLL> named_guids 
#include "DwgDataToXml.h"


CDwgDataToXml::CDwgDataToXml(void)
{
}


CDwgDataToXml::~CDwgDataToXml(void)
{
}

void CDwgDataToXml::Inlet()
{
	//图层
	struct resbuf* eb = NULL;
	eb = acutBuildList(-4, _T("<or"), 8, _T("最终路径"),                        
		-4, _T("or>"),NULL);

	CDwgDataToXml dwgDataToxml;
	AcGePoint3dArray vecXYPoint;//桩位XY坐标点
	dwgDataToxml.GetXYPoints(eb,vecXYPoint);
	if (vecXYPoint.length() <= 0)
		return ;

	CPointInfoArr arrPointData;
	dwgDataToxml.GetDataFromXZJ(eb,arrPointData,vecXYPoint);
	acutRelRb(eb);

	//写入xml文件
	if (arrPointData.size() > 0)
	{
		dwgDataToxml.WriteXml(arrPointData);
	}
}

BOOL CDwgDataToXml::GetIdArrayFromSS( ads_name selectSet,AcDbObjectIdArray &idArray )
{
	idArray.setLogicalLength(0);

	long len = 0;
	acedSSLength(selectSet,&len);

	if (acedSSLength(selectSet,&len) != RTNORM)		return FALSE;

	for(long i = 0; i < len; i++)
	{
		ads_name en_SS;
		if (acedSSName(selectSet,i,en_SS) != RTNORM)		return FALSE;

		AcDbObjectId enId_SS;
		if (acdbGetObjectId(enId_SS,en_SS) != Acad::eOk)		return FALSE;

		if (!enId_SS.isNull() && !idArray.contains(enId_SS))
		{
			idArray.append(enId_SS);
		}
	}

	return TRUE;
}

bool CDwgDataToXml::GetPosFromId( const AcDbObjectId &polyId,AcGePoint3dArray &vecPoint)
{
	//得到实体
	AcDbEntity* pEnt = NULL;
	Acad::ErrorStatus es = acdbOpenObject(pEnt,polyId,AcDb::kForRead);
	if (es != Acad::eOk)
		return false;

	if (pEnt->isA() == AcDbPolyline::desc())//多段线
	{
		AcDbPolyline *pPolyline = AcDbPolyline::cast(pEnt);
		for (int i = 0; i < pPolyline->numVerts(); i++)
		{
			AcGePoint3d pt;
			pPolyline->getPointAt(i,pt);
			vecPoint.append(pt);
		}
		pPolyline = NULL;
	}
	else
		acutPrintf(_T("\n选择实体不正确:\n"));

	return true;
}

void CDwgDataToXml::OnLoadDWG()
{
	//得到dwg图纸路径
	CDwgDataToXml dwgDataToxml;
	CString strPath = dwgDataToxml.GetDwgPath();

	//打开dwg图纸
	if(!dwgDataToxml.OpenDwg(strPath))
		acdbFail(_T("打开dwg图纸失败"));
}

void CDwgDataToXml::GetParentPath( CString & strPath )
{
	int nPos = strPath.ReverseFind(_T('\\'));
	strPath = strPath.Left(nPos);
	//strPath.TrimRight(_T("\\"));
}

CString CDwgDataToXml::GetDwgPath()
{
	TCHAR szFilePath[MAX_PATH+1];
	memset(szFilePath, 0, MAX_PATH+1);
	GetModuleFileName(_hdllInstance, szFilePath, MAX_PATH);

	CString strPath(szFilePath);
	GetParentPath(strPath);
	GetParentPath(strPath);
	GetParentPath(strPath);
	strPath = strPath + _T("\\Dwg\\CAD选线成果样例1.dwg");
	if (_taccess(strPath, 0) != -1)
	{
		//用户选择dwg
		CFileDialog dlg(FALSE, _T("*.dwg"), NULL, OFN_HIDEREADONLY, _T("AutoCAD File(*.dwg)|*.dwg||"),NULL);
		if ( dlg.DoModal() == IDOK )
			strPath = dlg.GetPathName();
	}

	return strPath;
}

BOOL CDwgDataToXml::OpenDwg( CString &strPath )
{
	//判断文件是否存在
	TCHAR fullpath[356]; 
	if (acedFindFile(strPath,fullpath) != RTNORM)
	{
		acdbFail(_T("工程文件没有找到!"));
		return TRUE;
	}
	//打开文件
	if (!acDocManager->isApplicationContext()) 
		return FALSE;

	// 查看文件是否已经打开,打开则不作处理
	AcApDocument *pDocOld;
	CString strFileName;
	AcApDocumentIterator *pIter  = acDocManager->newAcApDocumentIterator();
	Acad::ErrorStatus es = Acad::eOk;
	for(; !pIter->done(); pIter->step())
	{
		pDocOld = pIter->document();
		strFileName = pDocOld->fileName();
		if(strFileName.CompareNoCase(strPath) == 0)
		{
			delete pIter;
			es = acDocManager->setCurDocument(pDocOld,AcAp::kNone,true);

			return TRUE;
		}
	}
	delete pIter;

	// 没有打开
	if (!acDocManager->isApplicationContext()) 
		return FALSE;

	es = acDocManager->appContextOpenDocument((const TCHAR*)fullpath);
	if(es != Acad::eOk && es != Acad::eFilerError)	//注意!!!!如果是系统加载的时候会返回eFilerError
		return FALSE;

	return TRUE;
}

bool CDwgDataToXml::GetXYPoints(resbuf* eb, AcGePoint3dArray &vecPoint )
{
	//选择实体
	acutPrintf(_T("\n请选择实体:\n"));
	ads_name selectset;
	int rc = acedSSGet(_T(":S"),NULL,NULL,eb,selectset);// :S表示单选
	if (rc == RTCAN)//用户取消请求
	{
		acedSSFree(selectset);
		return false;
	}
	else if (rc != RTNORM)   
	{
		acutPrintf(_T("\n选择实体不正确:\n"));
		acedSSFree(selectset);
		return false;
	}

	//获得实体ID
	AcDbObjectIdArray arrMemberId;
	BOOL bRet = GetIdArrayFromSS(selectset,arrMemberId);
	acedSSFree(selectset);
	if (!bRet)
	{
		acutRelRb(eb);
		return false;
	}

	//获得实体的坐标点
	if (arrMemberId.length() == 1)
		GetPosFromId(arrMemberId[0], vecPoint);

	return true;
}

bool CDwgDataToXml::GetDataFromXZJ(resbuf* eb,CPointInfoArr& arrPointData,AcGePoint3dArray& vecXYPoint)
{
	ads_name SelName;
	int rc = acedSSGet(_T("X"), NULL, NULL,eb, SelName);
	if (rc != RTNORM)   
	{
		acedSSFree(SelName);
		return false;
	}

	long len = 0; 
	acedSSLength(SelName,&len);
	AcGePoint3dArray vecTextPoint;//桩位信息点
	CPointInfo ptData;
	for (long i = 0; i < len; i++)
	{
		ads_name entName;
		if (acedSSName(SelName, i, entName) != RTNORM) continue;

		AcDbObjectId eid;
		acdbGetObjectId(eid, entName);
		if (eid == NULL)
			continue;

		GetDataFromId(eid,ptData,vecXYPoint,arrPointData);
		if (!ptData.m_strPointName.IsEmpty())
			arrPointData.push_back(ptData);
	}

	acedSSFree(SelName);
	return true;
}

bool CDwgDataToXml::WriteXml(CPointInfoArr& arrPointData)
{
	CString strPath;
	GetUserSelectDir(strPath);

	CTime timeCurr = CTime::GetCurrentTime();
	CString strXmlName;
	strXmlName.Format(_T("\\桩位点数据%d%d%d%d%d%d.kml"),timeCurr.GetYear(),timeCurr.GetMonth(),timeCurr.GetDay(),
		timeCurr.GetHour(),timeCurr.GetMinute(),timeCurr.GetSecond());
	strPath+=strXmlName;
	strPath.Replace(_T("\\\\"), _T("\\"));

	if(arrPointData.SaveXMLFile(strPath))
		AfxMessageBox(_T("导出成功!"));
	else 
		AfxMessageBox(_T("写kml失败!"));

	return true;
}

bool CDwgDataToXml::GetDataFromId( AcDbObjectId &Id,CPointInfo& ptData,AcGePoint3dArray& vecXYPoint,CPointInfoArr& arrPointData )
{
	//得到实体
	AcDbEntity* pEnt = NULL;
	Acad::ErrorStatus es = acdbOpenObject(pEnt,Id,AcDb::kForRead);
	if (es != Acad::eOk)
		return false;

	if (pEnt->isA() == AcDbText::desc())
	{
		AcDbText *pText = AcDbText::cast(pEnt);
		ptData.m_strPointName = pText->textString();
		AcGePoint3d ptPoint = pText->position();
		m_mapLable[ptData.m_strPointName] = ptPoint;

		AcGePoint3d ptNearestPoint = GetNearestPoint(ptPoint,vecXYPoint);
		ptData.m_strPointX.Format(_T("%f"),ptNearestPoint.x);
		ptData.m_strPointY.Format(_T("%f"),ptNearestPoint.y);
		if (!IsAddArr(arrPointData,ptData,ptPoint,pEnt))
		{	//判断是否是不需要加入的数据,不需要加入就把名字置为空
			ptData.m_strPointName.Empty();
		}
		pText = NULL;
	}
	return true;
}

AcGePoint3d CDwgDataToXml::GetNearestPoint(const AcGePoint3d ptPoint,AcGePoint3dArray& vecXYPoint )
{
	AcGePoint3d ptNearestPoint;
	if (vecXYPoint.length() < 1)
		return ptNearestPoint;

	double dCurDistance = 0.0;
	double dMinDistance = (ptPoint - vecXYPoint[0]).length();
	ptNearestPoint = vecXYPoint[0];
	for (int nIndex = vecXYPoint.length() - 1; nIndex >= 0; --nIndex)
	{
		dCurDistance = (ptPoint - vecXYPoint[nIndex]).length();
		if(dCurDistance < dMinDistance)
		{
			dMinDistance = dCurDistance;
			ptNearestPoint = vecXYPoint[nIndex];	
		}	
	}

	return ptNearestPoint;
}

bool CDwgDataToXml::GetUserSelectDir( CString & strPath )
{
	strPath ='\0';
	TCHAR szPath[MAX_PATH];
	BROWSEINFO br;
	ITEMIDLIST * pItem; 
	br.hwndOwner = GetDesktopWindow();
	br.iImage = 0;
	br.pszDisplayName = 0;
	br.lParam = 0 ;
	br.lpfn = 0 ;
	br.lpszTitle = _T("请选择存放xml路径");
	br.pidlRoot = 0 ;
	br.ulFlags = BIF_RETURNONLYFSDIRS|BIF_USENEWUI;
	pItem = SHBrowseForFolder(&br);
	if (SHGetPathFromIDList(pItem,szPath) != TRUE)
	{
		return false;
	}

	strPath = szPath;
	return true;
}

bool CDwgDataToXml::IsAddArr( CPointInfoArr& arrPointData,CPointInfo& ptData,AcGePoint3d ptCurPoint,AcDbEntity* pTextEnt)
{
	if (ptData.m_strPointName.IsEmpty())
		return false;
	if (arrPointData.size() < 1)
		return true;

	AcGePoint3d ptPoint;
	AcGePoint3d ptXYPoint(_ttol(ptData.m_strPointX),_ttol(ptData.m_strPointY),0);//
	for (int nIndex = arrPointData.size() - 1; nIndex >= 0; --nIndex)
	{
		if (ptData.m_strPointX == arrPointData[nIndex].m_strPointX 
			&& ptData.m_strPointY == arrPointData[nIndex].m_strPointY )
		{
			ptPoint = m_mapLable[arrPointData[nIndex].m_strPointName];//现在标注的点

			if (!ModifNearestLabel(ptData))
			{
				double dPreDist = (ptPoint - ptXYPoint).length();
				double dCurDist = (ptCurPoint - ptXYPoint).length();
				if (dPreDist > dCurDist)
					arrPointData.erase(arrPointData.begin() + nIndex);
				else
					return false;
				break;
			}
		}
	}

	return true;
}

bool CDwgDataToXml::ModifNearestLabel(CPointInfo& ptData)
{
	struct resbuf* eb = NULL;
	eb = acutBuildList(-4, _T("<or"), 8, _T("最终路径"),                        
		-4, _T("or>"),NULL);
	ads_name SelName;
	AcGePoint3d ptPoint(_ttol(ptData.m_strPointX),_ttol(ptData.m_strPointY),0);
	int nRange = 10;//范围
	AcGePoint3d ptMin(ptPoint.x - nRange,ptPoint.y + nRange,0);
	AcGePoint3d ptMax(ptPoint.x + nRange,ptPoint.y - nRange,0);
	int iRet = acedSSGet(_T("W"), asDblArray(ptMin), asDblArray(ptMax), eb, SelName);
	acutRelRb(eb);
	if (iRet != RTNORM)
	{
		acedSSFree(SelName);
		return false;
	}

	long len = 0; 
	acedSSLength(SelName,&len);
	if (len != 1)
	{
		return false;
	}

	AcDbObjectId Id;
	acdbGetObjectId(Id, SelName);
	acedSSFree(SelName);
	if (NULL == Id)
		return false;

	//得到实体
	AcDbEntity* pEnt = NULL;
	Acad::ErrorStatus es = acdbOpenObject(pEnt,Id,AcDb::kForRead);
	if (Acad::eOk != es)
		return false;

	if (pEnt->isA() == AcDbText::desc())
	{
		AcDbText *pText = AcDbText::cast(pEnt);
		ptData.m_strPointName = pText->textString();
		AcGePoint3d ptPoint = pText->position();
		ptData.m_strPointX.Format(_T("%f"),ptPoint.x);
		ptData.m_strPointY.Format(_T("%f"),ptPoint.y);
	}

	return true;
}

此处用了xml提供的一些方法,暂且封装,以便xml与数据结构之间的交互

XMLExt.h

#pragma once
#include <msxml2.h>
#include <vector>
#import <MSXML.DLL> named_guids 

/////////////////////////////////////////////////////////////////////////////////////////////
// class CHHXMLNodePtr 对MSXML::IXMLDOMNodePtr的封装 
/////////////////////////////////////////////////////////////////////////////////////////////
class __declspec(dllexport) CHHXMLNodePtr
{
public:
	CHHXMLNodePtr(void);
	CHHXMLNodePtr(MSXML::IXMLDOMNodePtr ptr);
	virtual ~CHHXMLNodePtr(void);
public:
	CHHXMLNodePtr& operator =( MSXML::IXMLDOMNodePtr ptr);
protected:
	MSXML::IXMLDOMElementPtr m_pNode;// 当前节点指针
public:
	//-----------------------------------------------------------------------------------
	// 函 数 名:GetNodeVar 
	// 函数介绍:[Gettext]m_pNode节点下,名字为lpNodeName的子节点值[用于m_pNode节点下只有一个名为lpNodeName的子节点的情况]
	// 参数介绍:LPCTSTR lpNodeName             子节点名
	//           OUT _HHReWrite CString* strVar 值
	// 返 回 值:virtual bool
	//-----------------------------------------------------------------------------------
	bool GetNodeVar(LPCTSTR lpNodeName,  CString* mVar);
	bool GetNodeVar(LPCTSTR lpNodeName, CString& mVar);
	bool GetNodeVar(LPCTSTR lpNodeName,  int      &mVar);
	bool GetNodeVar(LPCTSTR lpNodeName,  long     &mVar);
	bool GetNodeVar(LPCTSTR lpNodeName,  unsigned &mVar);
	bool GetNodeVar(LPCTSTR lpNodeName,  double   &mVar);


	bool GetVar( CString* mVar);
	bool GetVar(CString& mVar);
	bool GetVar(  int      &mVar);
	bool GetVar(  long     &mVar);
	bool GetVar(  unsigned &mVar);
	bool GetVar(  double   &mVar);

	// [Puttext]保存节点值,用于m_pNode节点下只有一个lpNodeName的情况,lpNodeName不存在,则会默认创建 
	bool SetNodeVar (LPCTSTR lpNodeName, LPCTSTR lpVar);
	bool SetNodeVarV(LPCTSTR lpNodeName, LPCTSTR lpFmt,...);

	// 无论lpNodeName节点是否存在,都创建新的lpNodeName节点,给新节点赋值
	bool SetNewNodeVar (LPCTSTR lpNodeName, LPCTSTR lpVar);
	bool SetNewNodeVarV(LPCTSTR lpNodeName, LPCTSTR lpFmt,...);

public:// 操作当前节点属性

	// 取得属性值 
	bool GetAttribute( LPCTSTR lpAttriName, CString* mVar);
	bool GetAttribute( LPCTSTR lpAttriName, CString& mVar);
	bool GetAttribute( LPCTSTR lpAttriName,  int      &mVar);
	bool GetAttribute( LPCTSTR lpAttriName,  long     &mVar);
	bool GetAttribute( LPCTSTR lpAttriName,  unsigned &mVar);
	bool GetAttribute( LPCTSTR lpAttriName,  double   &mVar);
	bool GetAttribute( std::map<CString, CString>& mapName2Value);
	bool GetNodeName(CString& strName);

	// 写属性
	bool SetAttribute ( LPCTSTR lpAttriName,LPCTSTR lpVar);
	bool SetAttributeV( LPCTSTR lpAttriName,LPCTSTR lpFmt,...);

public:// 操作子项属性

	// 取得属性值 
	bool GetSubAttribute(LPCTSTR lpNodeName, LPCTSTR lpAttriName,  CString* mVar);
	bool GetSubAttribute(LPCTSTR lpNodeName, LPCTSTR lpAttriName,  CString& mVar);
	bool GetSubAttribute(LPCTSTR lpNodeName, LPCTSTR lpAttriName,  int      &mVar);
	bool GetSubAttribute(LPCTSTR lpNodeName, LPCTSTR lpAttriName,  long     &mVar);
	bool GetSubAttribute(LPCTSTR lpNodeName, LPCTSTR lpAttriName,  unsigned &mVar);
	bool GetSubAttribute(LPCTSTR lpNodeName, LPCTSTR lpAttriName,  double   &mVar);

	// 写属性
	bool SetSubAttribute (LPCTSTR lpNodeName, LPCTSTR lpAttriName,LPCTSTR lpVar);
	bool SetSubAttributeV(LPCTSTR lpNodeName, LPCTSTR lpAttriName,LPCTSTR lpFmt,...);
public:
	//-----------------------------------------------------------------------------------
	// 函 数 名:SetToSubPtr 
	// 函数介绍:将当前m_pNode指向lpNodeName子节点[适用于子弟节点只有一个名为lpNodeName的情况]
	// 参数介绍:LPCTSTR lpNodeName      节点名称
	//			 bool bIsAutoCreate=true 节点不存在时,是否自动创建
	// 返 回 值:bool true:成功,false:失败
	//-----------------------------------------------------------------------------------
	bool SetToSubPtr(LPCTSTR lpNodeName, bool bIsAutoCreate=false);

	//-----------------------------------------------------------------------------------
	// 函 数 名:SetToBrotherPtr
	// 函数介绍:将当前m_pNode指向lpNodeName兄弟节点[适用于兄弟节点只有一个名为lpNodeName的情况]
	// 参数介绍:LPCTSTR lpNodeName       节点名称
	//           bool bIsAutoCreate=false 节点不存在时,是否自动创建
	// 返 回 值:bool true:成功,false:失败
	//-----------------------------------------------------------------------------------
	bool SetToBrotherPtr(LPCTSTR lpNodeName, bool bIsAutoCreate=false);
	bool SetToBrotherPtr2(LPCTSTR lpNodeName);
	bool GetSubNodePtr(std::vector<IXMLDOMNodePtr>& vecSubNode);

	// 取得节点指针 
	MSXML::IXMLDOMElementPtr GetNodePtr()const{return m_pNode;}

	// 得到子节点,如果失败,则返回空【不改变当前节点】 
	MSXML::IXMLDOMElementPtr GetNodeSubPtr(LPCTSTR lpSubName)const;

	// 得到兄弟节点,如果失败,则返回空【不改变当前节点】 
	MSXML::IXMLDOMElementPtr GetNodeBrotherPtr(LPCTSTR lpNodeName)const;
};

XMLExt.cpp

#include "StdAfx.h"
#include "XMLExt.h"
#import <MSXML.DLL> named_guids

CHHXMLNodePtr::CHHXMLNodePtr(void)
{
}
CHHXMLNodePtr::CHHXMLNodePtr(MSXML::IXMLDOMNodePtr ptr)
{
	*this = ptr;
}
CHHXMLNodePtr::~CHHXMLNodePtr(void)
{
}
CHHXMLNodePtr& CHHXMLNodePtr::operator =( MSXML::IXMLDOMNodePtr ptr)
{
	m_pNode = ptr;
	return *this;
}

//-----------------------------------------------------------------------------------
// 函 数 名:GetNodeVar 
// 函数介绍:[Gettext]m_pNode节点下,名字为lpNodeName的子节点值[用于m_pNode节点下只有一个名为lpNodeName的子节点的情况]
// 参数介绍:LPCTSTR lpNodeName             子节点名
//           OUT _HHReWrite CString* strVar 值
// 返 回 值:virtual bool
//-----------------------------------------------------------------------------------
bool CHHXMLNodePtr::GetNodeVar(LPCTSTR lpNodeName,CString* mVar)
{
	return GetNodeVar( lpNodeName, *mVar);
}
bool CHHXMLNodePtr::GetNodeVar(LPCTSTR lpNodeName,CString& mVar)
{
	try
	{
		// 取得节点
		MSXML::IXMLDOMNodePtr pSingleNode = m_pNode->selectSingleNode(lpNodeName);
		if ( NULL == pSingleNode )
			return false;

		mVar = (LPCTSTR)pSingleNode->Gettext();
	}
	catch (...)
	{
		return false;
	}
	return true;
}
bool CHHXMLNodePtr::GetNodeVar(LPCTSTR lpNodeName, OUT int      &mVar)
{
	CString strVar;
	if ( !GetNodeVar(lpNodeName, &strVar) )
		return false;

	mVar = _ttoi(strVar);
	return true;
}
bool CHHXMLNodePtr::GetNodeVar(LPCTSTR lpNodeName, OUT long     &mVar)
{
	CString strVar;
	if ( !GetNodeVar(lpNodeName, &strVar) )
		return false;

	mVar = _ttol(strVar);
	return true;
}
bool CHHXMLNodePtr::GetNodeVar(LPCTSTR lpNodeName, OUT unsigned &mVar)
{
	CString strVar;
	if ( !GetNodeVar(lpNodeName, &strVar) )
		return false;

	mVar = _ttoi(strVar);
	return true;
}
bool CHHXMLNodePtr::GetNodeVar(LPCTSTR lpNodeName, OUT double &mVar)
{
	CString strVar;
	if ( !GetNodeVar(lpNodeName, &strVar) )
		return false;

	mVar = _tstof(strVar);
	return true;
}

//////////////////////////////////////////////////////////////////////////
//! @brief 
//! @param bool bIsForceCreateNew/*=true*/ 是否强制增加新项,如果为false则修改已有节点的值
//! @param LPCTSTR lpNodeName 节点名
//! @param LPCTSTR lpVar      节点值
//! @exception
//! @return bool
//! @sa 
// -----------------------------------------------------------------------
//	
//	版本:		1.0
// 
//////////////////////////////////////////////////////////////////////////
bool CHHXMLNodePtr::SetNodeVar( LPCTSTR lpNodeName, LPCTSTR lpVar)
{
	try
	{
		// 取得节点
		MSXML::IXMLDOMNodePtr pSingleNode = m_pNode->selectSingleNode(lpNodeName);
		if ( NULL == pSingleNode )
		{
			pSingleNode = m_pNode->GetownerDocument()->createElement(lpNodeName);
			if(!m_pNode->appendChild(pSingleNode));
				return false;
		}
		pSingleNode->Puttext(lpVar);
	}
	catch (...)
	{
		return false;
	}
	return true;
}

bool CHHXMLNodePtr::SetNodeVarV( LPCTSTR lpNodeName, LPCTSTR lpFmt,...)
{
	CString strVar;
	va_list mList;
	va_start(mList, lpFmt);
	strVar.FormatV(lpFmt, mList);
	va_end(mList);

	return SetNodeVar( lpNodeName, strVar);
}

//////////////////////////////////////////////////////////////////////////
//! @brief 
//! @param LPCTSTR lpNodeName
//! @param LPCTSTR lpVar
//! @exception
//! @return bool
//! @sa 
// -----------------------------------------------------------------------
//	版本:		1.0
// 
//////////////////////////////////////////////////////////////////////////
bool CHHXMLNodePtr::SetNewNodeVar( LPCTSTR lpNodeName, LPCTSTR lpVar )
{
	try
	{
		// 取得节点
		MSXML::IXMLDOMNodePtr pSingleNode = m_pNode->GetownerDocument()->createElement(lpNodeName);
		if(!m_pNode->appendChild(pSingleNode))
			return false;
		pSingleNode->Puttext(lpVar);
	}
	catch (...)
	{
		return false;
	}
	return true;
}

//////////////////////////////////////////////////////////////////////////
//! @brief 
//! @param LPCTSTR lpNodeName
//! @param LPCTSTR lpFmt
//! @param ...
//! @exception
//! @return bool
//! @sa 
// -----------------------------------------------------------------------
//	版本:		1.0
// 
//////////////////////////////////////////////////////////////////////////
bool CHHXMLNodePtr::SetNewNodeVarV( LPCTSTR lpNodeName, LPCTSTR lpFmt,... )
{
	CString strVar;
	va_list mList;
	va_start(mList, lpFmt);
	strVar.FormatV(lpFmt, mList);
	va_end(mList);

	return SetNewNodeVar( lpNodeName, strVar);
}

//-----------------------------------------------------------------------------------
// 函 数 名:SetToSubPtr 
// 函数介绍:将当前m_pNode指向lpNodeName子节点
// 参数介绍:LPCTSTR lpNodeName
//			 bool bIsAutoCreate=true 节点不存在时,是否自动创建
// 返 回 值:bool true:成功,false:失败
//-----------------------------------------------------------------------------------
bool CHHXMLNodePtr::SetToSubPtr(LPCTSTR lpNodeName, bool bIsAutoCreate/*=false*/)
{
	try
	{
		// 取得节点
		MSXML::IXMLDOMNodePtr pSingleNode = m_pNode->selectSingleNode(lpNodeName);
		if ( NULL == pSingleNode )
		{
			if ( !bIsAutoCreate )
				return false;
			pSingleNode = m_pNode->GetownerDocument()->createElement(lpNodeName);
			m_pNode->appendChild(pSingleNode);
		}
		m_pNode = pSingleNode;
	}
	catch (...)
	{
		return false;
	}
	return true;
}

//-----------------------------------------------------------------------------------
// 函 数 名:SetToBrotherPtr 
// 函数介绍:将当前m_pNode指向lpNodeName兄弟节点[适用于兄弟节点只有一个名为lpNodeName的情况]
// 参数介绍:LPCTSTR lpNodeName       节点名称
//           bool bIsAutoCreate=false 节点不存在时,是否自动创建
// 返 回 值:bool true:成功,false:失败
//-----------------------------------------------------------------------------------
bool CHHXMLNodePtr::SetToBrotherPtr(LPCTSTR lpNodeName, bool bIsAutoCreate/*=false*/)
{
	try
	{
		// 取得父节点
		MSXML::IXMLDOMNodePtr pParentNode;
		if(!m_pNode->get_parentNode(&pParentNode))
			return false;

		// 取得兄弟节点
		MSXML::IXMLDOMNodePtr pSingleNode = pParentNode->selectSingleNode(lpNodeName);
		if ( NULL == pSingleNode )
		{
			if ( !bIsAutoCreate )
				return false;
			pSingleNode = pParentNode->GetownerDocument()->createElement(lpNodeName);
			pParentNode->appendChild(pSingleNode);
		}
		m_pNode = pSingleNode;
	}
	catch (...)
	{
		return false;
	}
	return true;
}

// 找子节点没找到则找兄弟节点
bool CHHXMLNodePtr::SetToBrotherPtr2(LPCTSTR lpNodeName)
{
	try
	{
		// 取得子节点
		MSXML::IXMLDOMNodePtr pSingleNode = m_pNode->selectSingleNode(lpNodeName);
		if ( NULL == pSingleNode )
		{
			// 取得兄弟节点
			MSXML::IXMLDOMNodePtr pParentNode;
			if(!m_pNode->get_parentNode(&pParentNode))
				return false;
			pSingleNode = pParentNode->selectSingleNode(lpNodeName);
			if ( NULL == pSingleNode )
				return false;
		}
		m_pNode = pSingleNode;
	}
	catch (...)
	{
		return false;
	}
	return true;
}
//////////////////////////////////////////////////////////////////////////
//! @brief 
//! @param LPCTSTR lpNodeName  节点名
//! @param LPCTSTR lpAttriName 属性名
//! @param OUT _HHReWrite CString* mVar
//! @exception
//! @return bool
//! @sa 
// -----------------------------------------------------------------------
//	版本:		1.0
//
//////////////////////////////////////////////////////////////////////////
bool CHHXMLNodePtr::GetSubAttribute( LPCTSTR lpNodeName, LPCTSTR lpAttriName,CString* mVar )
{
	if (mVar == NULL)
		return false;

	try
	{
		// 取得节点
		MSXML::IXMLDOMNodePtr pSingleNode = m_pNode->selectSingleNode(lpNodeName);
		if ( NULL == pSingleNode )
			return false;
		// 取得属性
		MSXML::IXMLDOMNamedNodeMapPtr pAttris = pSingleNode->Getattributes();
		if ( NULL == pAttris )
			return false;

		// 找到属性
		MSXML::IXMLDOMNodePtr pItem = pAttris->getNamedItem(lpAttriName);
		if ( NULL == pItem )
			return false;

		// 取得值
		*mVar = (LPCTSTR)(pItem->Gettext());
	}
	catch (...)
	{
		return false;
	}
	return true;
}

bool CHHXMLNodePtr::GetSubAttribute(LPCTSTR lpNodeName, LPCTSTR lpAttriName,CString& mVar)
{
	return GetSubAttribute(lpNodeName, lpAttriName, &mVar);
}

bool CHHXMLNodePtr::GetSubAttribute(LPCTSTR lpNodeName, LPCTSTR lpAttriName, OUT int      &mVar)
{
	CString strVar;
	if ( !GetSubAttribute(lpNodeName, lpAttriName, &strVar) )
		return false;

	mVar = _ttoi(strVar);
	return true;
}
bool CHHXMLNodePtr::GetSubAttribute(LPCTSTR lpNodeName, LPCTSTR lpAttriName, OUT long     &mVar)
{
	CString strVar;
	if ( !GetSubAttribute(lpNodeName, lpAttriName, &strVar) )
		return false;

	mVar = _ttol(strVar);
	return true;
}
bool CHHXMLNodePtr::GetSubAttribute(LPCTSTR lpNodeName, LPCTSTR lpAttriName, OUT unsigned &mVar)
{
	CString strVar;
	if ( !GetSubAttribute(lpNodeName, lpAttriName, &strVar) )
		return false;

	mVar = _ttoi(strVar);
	return true;
}
bool CHHXMLNodePtr::GetSubAttribute(LPCTSTR lpNodeName, LPCTSTR lpAttriName, OUT double &mVar)
{
	CString strVar;
	if ( !GetSubAttribute(lpNodeName, lpAttriName, &strVar) )
		return false;

	mVar = _tstof(strVar);
	return true;
}

//////////////////////////////////////////////////////////////////////////
//! @brief 写属性值【如果属性不存在,则自动创建】
//! @param LPCTSTR lpNodeName  节点名
//! @param LPCTSTR lpAttriName 属性名
//! @param LPCTSTR lpVar
//! @exception
//! @return bool
//! @sa 
// -----------------------------------------------------------------------
//	版本:		1.0
//////////////////////////////////////////////////////////////////////////
bool CHHXMLNodePtr::SetSubAttribute( LPCTSTR lpNodeName, LPCTSTR lpAttriName,LPCTSTR lpVar )
{
	try
	{
		// 取得节点
		MSXML::IXMLDOMElementPtr pSingleNode = m_pNode->selectSingleNode(lpNodeName);
		if ( NULL == pSingleNode )
		{
			pSingleNode = m_pNode->GetownerDocument()->createElement(lpNodeName);
			if(!m_pNode->appendChild(pSingleNode))
				return false;
		}

		pSingleNode->setAttribute(lpAttriName, lpVar);
	}
	catch (...)
	{
		return false;
	}
	return true;
}
bool CHHXMLNodePtr::SetSubAttributeV(LPCTSTR lpNodeName, LPCTSTR lpAttriName, LPCTSTR lpFmt,...)
{
	CString strVar;
	va_list mList;
	va_start(mList, lpFmt);
	strVar.FormatV(lpFmt, mList);
	va_end(mList);

	return SetSubAttribute(lpNodeName, lpAttriName, strVar);
}
//////////////////////////////////////////////////////////////////////////
//! @brief 
//! @param LPCTSTR lpAttriName
//! @param OUT _HHReWrite CString* mVar
//! @exception
//! @return bool
//! @sa 
// -----------------------------------------------------------------------
//	版本:		1.0
//////////////////////////////////////////////////////////////////////////
bool CHHXMLNodePtr::GetAttribute( LPCTSTR lpAttriName, CString* mVar )
{
	if(m_pNode==NULL || mVar==NULL)
		return false;

	try
	{
		// 取得属性
		MSXML::IXMLDOMNamedNodeMapPtr pAttris = m_pNode->Getattributes();
		if ( NULL == pAttris )
			return false;

		// 找到属性
		MSXML::IXMLDOMNodePtr pItem = pAttris->getNamedItem(lpAttriName);
		if ( NULL == pItem )
			return false;

		// 取得值
		*mVar = (LPCTSTR)(pItem->Gettext());
	}
	catch (...)
	{
		return false;
	}
	return true;
}

bool CHHXMLNodePtr::GetAttribute( LPCTSTR lpAttriName,CString& mVar)
{
	return GetAttribute( lpAttriName, &mVar);
}

bool CHHXMLNodePtr::GetAttribute(LPCTSTR lpAttriName,  int      &mVar)
{
	CString strVar;
	if ( !GetAttribute( lpAttriName, &strVar) )
		return false;

	mVar = _ttoi(strVar);
	return true;
}
bool CHHXMLNodePtr::GetAttribute(LPCTSTR lpAttriName, OUT long     &mVar)
{
	CString strVar;
	if ( !GetAttribute( lpAttriName, &strVar) )
		return false;

	mVar = _ttol(strVar);
	return true;
}
bool CHHXMLNodePtr::GetAttribute( LPCTSTR lpAttriName, OUT unsigned &mVar)
{
	CString strVar;
	if ( !GetAttribute( lpAttriName, &strVar) )
		return false;

	mVar = _ttoi(strVar);
	return true;
}
bool CHHXMLNodePtr::GetAttribute( LPCTSTR lpAttriName, OUT double &mVar)
{
	CString strVar;
	if ( !GetAttribute( lpAttriName, &strVar) )
		return false;

	mVar = _tstof(strVar);
	return true;
}

bool CHHXMLNodePtr::GetAttribute( std::map<CString, CString>& mapName2Value )
{
	if(m_pNode==NULL)
		return false;
	try
	{
		// 取得属性
		MSXML::IXMLDOMNamedNodeMapPtr pAttris = m_pNode->Getattributes();
		if ( NULL == pAttris )
			return false;

		for (int i=0; i<pAttris->length; ++i)
		{
			MSXML::IXMLDOMNodePtr pItem = pAttris->Getitem(i);
			if ( NULL == pItem )
				continue;
			CString strName((TCHAR*)pItem->nodeName);
			mapName2Value[strName] = CString((TCHAR*)pItem->text);
		}
	}
	catch (...)
	{
		return false;
	}
	return true;
}

//////////////////////////////////////////////////////////////////////////
//! @brief 写属性值【如果属性不存在,则自动创建】
//! @param LPCTSTR lpNodeName  节点名
//! @param LPCTSTR lpAttriName 属性名
//! @param LPCTSTR lpVar
//! @exception
//! @return bool
//! @sa 
// -----------------------------------------------------------------------
//	版本:		1.0
//////////////////////////////////////////////////////////////////////////
bool CHHXMLNodePtr::SetAttribute(  LPCTSTR lpAttriName,LPCTSTR lpVar )
{
	try
	{
		m_pNode->setAttribute(lpAttriName, lpVar);
	}
	catch (...)
	{
		return false;
	}
	return true;
}
bool CHHXMLNodePtr::SetAttributeV(LPCTSTR lpAttriName, LPCTSTR lpFmt,...)
{
	CString strVar;
	va_list mList;
	va_start(mList, lpFmt);
	strVar.FormatV(lpFmt, mList);
	va_end(mList);

	return SetAttribute(lpAttriName, strVar);
}

//////////////////////////////////////////////////////////////////////////
//! @brief 
//! @param LPCTSTR lpSubName
//! @exception
//! @return MSXML::IXMLDOMElementPtr
//! @sa 
// -----------------------------------------------------------------------
//	版本:		1.0
//////////////////////////////////////////////////////////////////////////
MSXML::IXMLDOMElementPtr CHHXMLNodePtr::GetNodeSubPtr( LPCTSTR lpSubName ) const
{
	try
	{
		// 取得节点
		return m_pNode->selectSingleNode(lpSubName);
	}
	catch (...)
	{
	}

	return NULL;
}

//////////////////////////////////////////////////////////////////////////
//! @brief 
//! @param LPCTSTR lpNodeName
//! @exception
//! @return MSXML::IXMLDOMElementPtr
//! @sa 
// -----------------------------------------------------------------------
//
//	版本:		1.0
//////////////////////////////////////////////////////////////////////////
MSXML::IXMLDOMElementPtr CHHXMLNodePtr::GetNodeBrotherPtr( LPCTSTR lpNodeName ) const
{
	try
	{
		// 取得父节点
		MSXML::IXMLDOMNodePtr pParentNode;
		if(!m_pNode->get_parentNode(&pParentNode))
			return NULL;

		// 取得兄弟节点
		MSXML::IXMLDOMNodePtr pSingleNode = pParentNode->selectSingleNode(lpNodeName);
		return pSingleNode;
	}
	catch (...)
	{
	}
	return NULL;
}

bool CHHXMLNodePtr::GetVar( CString* mVar )
{
		return GetVar( *mVar);
}

bool CHHXMLNodePtr::GetVar(CString& mVar )
{
	try
	{
		// 取得节点
		if ( NULL == m_pNode )
			return false;

		mVar = (LPCTSTR)m_pNode->Gettext();
	}
	catch (...)
	{
		return false;
	}
	return true;

}

bool CHHXMLNodePtr::GetVar(int &mVar )
{
	CString strVar;
	if ( !GetVar( &strVar) )
		return false;

	mVar = _ttoi(strVar);
	return true;

}

bool CHHXMLNodePtr::GetVar(long &mVar )
{
	CString strVar;
	if ( !GetVar( &strVar) )
		return false;

	mVar = _ttol(strVar);
	return true;

}

bool CHHXMLNodePtr::GetVar( OUT unsigned &mVar )
{
	CString strVar;
	if ( !GetVar( &strVar) )
		return false;

	mVar = _ttoi(strVar);
	return true;

}

bool CHHXMLNodePtr::GetVar( OUT double &mVar )
{
	CString strVar;
	if ( !GetVar( &strVar) )
		return false;

	mVar = _tstof(strVar);
	return true;

}

bool CHHXMLNodePtr::GetSubNodePtr( std::vector<IXMLDOMNodePtr>& vecSubNode )
{
	try
	{
		// 取得子节点
		MSXML::IXMLDOMNodeList *pChildList(NULL);
		if (S_OK != m_pNode->get_childNodes(&pChildList) || NULL == pChildList)
			return false;

		for (int i=0; i<pChildList->Getlength(); ++i)
		{
			IXMLDOMNodePtr pItem = pChildList->Getitem(i);
			if (NULL == pItem)
				continue;
			vecSubNode.push_back(pItem);
		}
	}
	catch (...)
	{
		return false;
	}
	return true;
}

bool CHHXMLNodePtr::GetNodeName( CString& strName )
{
	BSTR bstr = NULL;
	if (S_OK != m_pNode->get_nodeName(&bstr) || NULL == bstr)
		return false;
	strName = (TCHAR*)bstr;
	return true;
}

PrjStruct.h

#pragma once
#include <vector>
#include <msxml2.h>
#import <MSXML.DLL> named_guids

class CIniFileN;
/////////////////////////////////////////////////////////////////////////////////////////////
// class CXMLElement 保存、合成XML格式的基类 
/////////////////////////////////////////////////////////////////////////////////////////////
interface __declspec(dllexport) CXMLElement
{
public:
	CXMLElement():m_strverencoding(_T("version=\'1.0\'")){}
	virtual ~CXMLElement(){}
public:
	// 读取XML格式的字符串,给成员赋值 
	virtual bool LoadXML(IN LPCTSTR lpXMLStr)=0;
	virtual bool LoadXML(MSXML::IXMLDOMNodePtr pNode)=0;

	// 将成员值,保存为XML格式
	virtual bool SaveXML( CString* strXML)const=0;
	virtual bool SaveXML( MSXML::IXMLDOMNodePtr pNode)const=0;

	// 函数自测试 
	virtual bool SelfTest(){return false;};

	// 取得根节点名
	LPCTSTR GetRootNodeIn()const{return GetRootNode();}
public:
	// 保存到XML文件 
	virtual bool SaveXMLFile(LPCTSTR lpFileName)const;

	// 读取XML文件 
	virtual bool LoadXMLFile(LPCTSTR lpFileName);

	// [需要GetRootNode()节点] 
	virtual bool LoadNodeXML(MSXML::IXMLDOMNodePtr pNode)=0;

	// 将成员值,保存为XML格式 
	virtual bool SaveNodeXML( MSXML::IXMLDOMNodePtr pNode)const=0;

	// 取得根节点名 
	virtual LPCTSTR GetRootNode()const=0;

	// 设置xml文件头部的version='1.0' encoding='GB2312',默认为 version='1.0',不指定编码方式
	void SetVersionEncoding(LPCTSTR lpverencod);

private:
	CString m_strverencoding;
};
/////////////////////////////////////////////////////////////////////////////////////////////
// struct CHHElement: public CXMLElement 对基类的次级封装,目的统一完成某几个函数 
/////////////////////////////////////////////////////////////////////////////////////////////
struct __declspec(dllexport) CHHElement: public CXMLElement
{
public:
	CHHElement();
	~CHHElement();
public:
	// 读取XML格式的字符串,给成员赋值 
	virtual bool LoadXML(IN LPCTSTR lpXMLStr);
	virtual bool LoadXML(MSXML::IXMLDOMNodePtr pNode){return LoadNodeXML(pNode);}

	// 将成员值,保存为XML格式 
	virtual bool SaveXML(CString* strXML)const;
	virtual bool SaveXML(MSXML::IXMLDOMNodePtr pNode)const{return SaveNodeXML(pNode);}
};


/////////////////////////////////////////////////////////////////////////////////////////////
// struct CArrBase  数组封装 
/////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
struct __declspec(dllexport) CArrBase: public std::vector<T>
{
public:

	// 查找序号 
	template<class _Pr>
	int Find(_Pr op )const
	{
		std::vector<T>::const_iterator mIter = std::find_if(begin(), end(), op);
		if ( mIter == end() )
			return -1;
		return mIter-begin();
	}

	template<class _Pr>
	std::vector<int> FindAll(_Pr op )const
	{
		std::vector<int> arrRet;
		for (int i=0; i<(int)size(); ++i)
		{
			if ( op(at(i)))
			{
				arrRet.push_back(i);
			}
		}
		return arrRet;
	}
	// 排序 
	template<class _Pr>
	__inline void Sort(_Pr op) { std::sort(begin(), end(), op); }
	__inline void Sort(){std::sort(begin(), end());}

	// 清除指定序号记录 
	__inline virtual void RemoveAt(int nIndex)
	{ 
		if ( nIndex>=0 && nIndex<(int)size() )
		{
			erase(begin()+nIndex); 
		}
	}
};

/////////////////////////////////////////////////////////////////////////////////////////////
// struct CArrElementTest: protected CArrBase<CXMLElement*> 元素自测试数组 
/////////////////////////////////////////////////////////////////////////////////////////////
struct __declspec(dllexport) CArrElementTest: protected CArrBase<CXMLElement*>
{
public:
	CArrElementTest();
	virtual ~CArrElementTest();
public:
	// 添加一个测试实体 
	template<class T>
	void Add()
	{
		T* pItem = new T;
		push_back(pItem);
	}
	// 清除全部 
	virtual void clear();
	// 进行自测试 
	virtual void TestAll();
};

/////////////////////////////////////////////////////////////////////////////////////////////
// struct CArrElementBase: public CHHElement, public CArrBase<T>  元素数组操作封装 
/////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
struct __declspec(dllexport) CArrElementBase: public CHHElement, public CArrBase<T>
{
	typedef const CArrBase<T>* _CArrBasePtr;
public:
	// 重载等号/不等号 
	bool operator == (const CArrElementBase&p1 )const { return *((_CArrBasePtr)this)==*((_CArrBasePtr)(&p1));}
	bool operator != (const CArrElementBase&p1 )const { return !(*this==p1); }
protected:
	// 读取XML格式的字符串,给成员赋值 
	virtual bool LoadNodeXML(MSXML::IXMLDOMNodePtr pNode)
	{
		try
		{
			// 解析取每个元素
			T tmp;
			MSXML::IXMLDOMNodeListPtr pNodeList = pNode->selectNodes(tmp.GetRootNodeIn());
			const int nCount = pNodeList->Getlength();
			if ( nCount < 1 )
				return true;

			// 循环创建每个元素信息
			for (int i=0; i<nCount; ++i)
			{
				// 取得节点信息
				T mInfo;
				if(!mInfo.LoadXML(pNodeList->Getitem(i)))
					 continue;
				push_back(mInfo);
			}
		}
		catch(...)
		{
			return false;
		}
		return true;
	}
	// 将成员值,保存为XML格式 
	virtual bool SaveNodeXML( MSXML::IXMLDOMNodePtr pNode)const
	{
		const int nCount = size();
		for (int i=0; i<nCount; ++i)
		{
			// 一条信息
			const T& mItem = at(i);
			try
			{
				// 创建一个节点
				MSXML::IXMLDOMNodePtr pNew = pNode->GetownerDocument()->createElement(mItem.GetRootNodeIn());
				if(!pNode->appendChild(pNew))
					 continue;

				// 保存节点信息
				if(!mItem.SaveXML(pNew))
					return false;
			}
			catch(...)
			{
				continue;
			}
		}
		return true;
	}
};

//桩位信息
class __declspec(dllexport) CPointInfo : public CHHElement
{
public:
	CPointInfo(){}
	~CPointInfo(){}

public:
	CString m_strPointX;
	CString m_strPointY;
	CString m_strPointName;	

protected:
	static LPCTSTR node_PointInfo;//节点

	static LPCTSTR glb_strPointX;
	static LPCTSTR glb_strPointY;
	static LPCTSTR glb_strPointName;
	
protected:
	virtual LPCTSTR GetRootNode()const{return GetSelfRoot();};
	virtual bool LoadNodeXML(MSXML::IXMLDOMNodePtr pNode);
	virtual bool SaveNodeXML( MSXML::IXMLDOMNodePtr pNode)const;

public:
	static LPCTSTR GetSelfRoot();
};

class __declspec(dllexport)	CPointInfoArr : public CArrElementBase<CPointInfo>
{
public:
	CPointInfoArr();
	virtual~CPointInfoArr();

protected:
	static LPCTSTR node_PointInfoArr;//节点

protected:
	virtual LPCTSTR GetRootNode()const{return GetSelfRoot();};

public:
	//读取XML格式的字符串
	virtual bool LoadNodeXML(MSXML::IXMLDOMNodePtr pNode);
	//保存成xml格式
	virtual bool SaveNodeXML(MSXML::IXMLDOMNodePtr pNode)const;

public:
	static LPCTSTR GetSelfRoot();
};

PrjStruct.cpp

#include "StdAfx.h"
#include "PrjStruct.h"
#include "XMLExt.h"
#import <MSXML.DLL> named_guids

//////////////////////////////////////////////////////////////////////////
//! @brief 
//! @param LPCTSTR lpFileName
//! @exception
//! @return bool
//! @sa 
// -----------------------------------------------------------------------
//	版本:		1.0
//////////////////////////////////////////////////////////////////////////
bool CXMLElement::SaveXMLFile( LPCTSTR lpFileName ) const
{
	try
	{
		// 创建根节点
		MSXML::IXMLDOMDocumentPtr pXmlDoc;
		if(pXmlDoc.CreateInstance(MSXML::CLSID_DOMDocument) != S_OK)
			return false; 

		MSXML::IXMLDOMProcessingInstructionPtr pi = pXmlDoc->createProcessingInstruction(_T("xml"), (LPCTSTR)m_strverencoding);
		_variant_t vNullVal;
		vNullVal.vt = VT_NULL;
		pXmlDoc->insertBefore(pi, vNullVal);

		MSXML::IXMLDOMNodePtr pRoot = pXmlDoc->createElement(GetRootNode());
		if(!pXmlDoc->appendChild(pRoot))
			return false;

		// 向节点中写信息
		if(!SaveNodeXML(pRoot))
			return false;

		// 取得XML信息
		pXmlDoc->save(lpFileName);
	}
	catch(...)
	{
		return false;
	}
	return true;
}

//////////////////////////////////////////////////////////////////////////
//! @brief 读取XML文件
//! @param LPCTSTR lpFileName XML文件名称
//! @exception
//! @return bool
//! @sa 
// -----------------------------------------------------------------------
//	版本:		1.0
//////////////////////////////////////////////////////////////////////////
bool CXMLElement::LoadXMLFile( LPCTSTR lpFileName )
{
	try
	{
		// 创建根节点
		MSXML::IXMLDOMDocumentPtr pXmlDoc;
		if(pXmlDoc.CreateInstance(MSXML::CLSID_DOMDocument) != S_OK)
			return false; 

		// 取得XML信息
		if(!pXmlDoc->load(lpFileName))
			return false;
		return LoadNodeXML(pXmlDoc->GetdocumentElement());
	}
	catch(...)
	{
		return false;
	}
	return true;
}

void CXMLElement::SetVersionEncoding(LPCTSTR lpverencod)
{
	if (lpverencod != NULL && lpverencod[0] != _T('\0'))
		m_strverencoding = lpverencod;
}

/////////////////////////////////////////////////////////////////////////////////////////////
// struct CHHElement: public CXMLElement 对基类的次级封装,目的统一完成某几个函数 
/////////////////////////////////////////////////////////////////////////////////////////////
CHHElement::CHHElement()
{
}
CHHElement::~CHHElement()
{
}
// 读取XML格式的字符串,给成员赋值
bool CHHElement::LoadXML(IN LPCTSTR lpXMLStr)
{
	try
	{
		// 载入字符串
		MSXML::IXMLDOMDocumentPtr pXmlDoc;
		if(pXmlDoc.CreateInstance(MSXML::CLSID_DOMDocument) != S_OK)
			return false;
		if(!pXmlDoc->loadXML(lpXMLStr));
			return false;

		if(!LoadNodeXML(pXmlDoc->GetdocumentElement()))
			return false;
	}
	catch(...)
	{
		return false;
	}
	return true;
}
// 将成员值,保存为XML格式 
bool CHHElement::SaveXML(CString* strXML)const
{
	try
	{
		// 创建根节点
		MSXML::IXMLDOMDocumentPtr pXmlDoc;
		if(pXmlDoc.CreateInstance(MSXML::CLSID_DOMDocument) != S_OK )
			return false;
		MSXML::IXMLDOMNodePtr pRoot = pXmlDoc->createElement(GetRootNode());
		if(!pXmlDoc->appendChild(pRoot))
			return false;

		// 向节点中写信息
		if(!SaveNodeXML(pRoot))
			return false;

		// 取得XML信息
		*strXML = (LPCTSTR)pXmlDoc->Getxml();
	}
	catch(...)
	{
		return false;
	}
	return true;
}


/////////////////////////////////////////////////////////////////////////////////////////////
// struct CArrElementTest: protected CArrBase<CXMLElement*> 元素自测试数组 
/////////////////////////////////////////////////////////////////////////////////////////////
CArrElementTest::CArrElementTest()
{
}
CArrElementTest::~CArrElementTest()
{
	clear();
}
void CArrElementTest::clear()
{
	const int nCount = size();
	for (int i=0; i<nCount; ++i)
	{
		delete at(i);
	}
	clear();

}
// 进行自测试 
void CArrElementTest::TestAll()
{
	const int nCount = size();
	for (int i=0; i<nCount; ++i)
	{
		if(!at(i)->SelfTest())
			return;
	}
}


//////////////////////////////桩位信息/////////////////////////
LPCTSTR CPointInfoArr::node_PointInfoArr = _T("Points");
CPointInfoArr::CPointInfoArr()
{

}
CPointInfoArr::~CPointInfoArr()
{

}

LPCTSTR CPointInfoArr::GetSelfRoot()
{
	return node_PointInfoArr;
}

bool CPointInfoArr::LoadNodeXML( MSXML::IXMLDOMNodePtr pNode )
{
	try
	{
		CHHXMLNodePtr pNodePtr(pNode);
		if(__super::LoadNodeXML(pNode))
			 return false;
	}
	catch(...)
	{
		return false;
	}

	return true;
}

bool CPointInfoArr::SaveNodeXML(MSXML::IXMLDOMNodePtr pNode ) const
{
	try
	{
		if(!__super::SaveNodeXML(pNode))
			 return false;
	}
	catch(...)
	{
		return false;
	}
	return true;
}

LPCTSTR CPointInfo::node_PointInfo		= _T("Point"		);
LPCTSTR CPointInfo::glb_strPointX		= _T("X"			);
LPCTSTR CPointInfo::glb_strPointY		= _T("Y"			);
LPCTSTR CPointInfo::glb_strPointName	= _T("Name"			);
LPCTSTR CPointInfo::GetSelfRoot()
{
	return node_PointInfo;
}

bool CPointInfo::LoadNodeXML( MSXML::IXMLDOMNodePtr pNode )
{
	try
	{
		CHHXMLNodePtr pNodePtr(pNode);
		pNodePtr.GetNodeVar(glb_strPointX,		 m_strPointX);
		pNodePtr.GetNodeVar(glb_strPointY,		 m_strPointY);
		pNodePtr.GetNodeVar(glb_strPointName,	 m_strPointName);
	}
	catch(...)
	{
		return false;
	}

	return true;
}

bool CPointInfo::SaveNodeXML(MSXML::IXMLDOMNodePtr pNode ) const
{
	try
	{
		CHHXMLNodePtr pNodePtr(pNode);
		pNodePtr.SetAttribute(glb_strPointX,		 m_strPointX);
		pNodePtr.SetAttribute(glb_strPointY,		 m_strPointY);
		pNodePtr.SetAttribute(glb_strPointName,	 m_strPointName);
	}
	catch(...)
	{
		return false;
	}

	return true;
}

猜你喜欢

转载自my.oschina.net/u/2930533/blog/1486756
今日推荐