xml解析器实现过程

一、解析

1)        控制台实现:仅支持英文&节点显示;

2)        识别中文;

媒体共享里面共享中文名称的文件

空字符串  ASCII 9 10 nl

二、显示

树形控件  点一个显示子节点

文件共享点开文件夹

应用敏捷的思想

 

      要求:解析xml文件,并在树形控件中进行显示,效果图如下:

实现过程:

       运用敏捷的思想,提交多个版本:

  1. 实现解析功能
  2. MFC制作显示界
  • 实现解析功能

                        在控制台下实现了xml文件的解析,获取节点数据。

                        使用expat解析库对xml进行解析,截取cyberlink库中xml相关文件。将整个xml解析成一个Node节点,通过getNNodes获取当前节点的子节点个数,getNode(i)获取第i个子节点,以及getValue(),getName()等一系列函数获取节点相关信息。

                        主要遇到的问题:

                        1)如上图所示,不识别中文,是编码方式UTF-8和GB2312的问题

                                  void UTF_8ToGB2312(char * pOut, const char *pText, int &pLen);解决该问题,读出数据后在显示的时候进行转码。

  •  MFC制作显示界面

                        控制台显示不够直观,决定采用MFC的Tree Ctrl来实现。                       

 遇到的问题:           

             1)数据怎样以树形结构显示?解析出来的是叶子节点上的数据,必须要显示父节点。              

                解决思路:父节点显示名称,叶子节点显示节点名称和节点数据                    

             2)获取要解析的xml文件路径                     

                 i)按钮加载图标                                     

        m_search.LoadBitmaps(IDB_SEARCH, 0, 0, 0);
	m_search.SubclassDlgItem(IDC_BROWSEXML, this);
	m_search.SizeToContent();

                        m_search为按钮控件对应的CBitmapButton类型的变量(此变量必须手动添加,不能用IDE添加,否则出错),按钮的OWERDROW属性设置为TRUE.                         IDB_SEARCH是要显示在按钮上的图片的ID,IDC_BROWSEXML是按钮的ID。

                ii)打开文件对话框,仅显示xml格式文件以供选择    

                  m_path 为编辑控件对应的CString类型的变量         

       

CFileDialog hFileDlg(TRUE,NULL,NULL,OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_READONLY,
		TEXT("仅支持xml格式(*.xml;...)|*.xml"),NULL);
	if(IDOK == hFileDlg.DoModal())
	{
		m_path =_T("");
		m_path = hFileDlg.GetPathName();
		UpdateData(FALSE);
	}


       

  3)树形控件的使用及数据的显示

     

//*****************************************************
//	\brief		初始化树形控件
//
//	version:	普通版本
//
//	\author		huyp
//
//	\param		无
//
//	\return		无
//*****************************************************
void CHYPXmlParserDlg::InitXmlTree(void)
{
	DWORD dwStyles = GetWindowLong(m_TreeCtrl.m_hWnd,GWL_STYLE);//获取树控制原风格
	dwStyles|=TVS_EDITLABELS|TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT;
	SetWindowLong(m_TreeCtrl.m_hWnd,GWL_STYLE,dwStyles);//设置风格
}


 

//*****************************************************
//	\brief		显示XML数据
//
//	version:	普通版本
//
//	\author		huyp
//
//	\param		xmlNode  节点指针
//
//	\return		-1显示失败,1显示成功
//*****************************************************
int CHYPXmlParserDlg::ShowXmlData(Node* xmlNode)
{
	/*string buf;
	xmlNode->toString(buf);*/
    int nNodes = 0;
	if(NULL == xmlNode)//当前要显示的节点为空
	{
		return -1; 
	}
	
	nNodes = xmlNode->getNNodes();//获取当前节点的子节点个数

	if(0 == nNodes)//无子节点,是叶子节点
	{
		const char * value = xmlNode->getValue();
		const char * name = xmlNode->getName();
		char svalue[1024];
		char eleValue[1024];
		int lvalue = strlen(value);
		memset(svalue,0,sizeof(svalue));
		memset(eleValue,0,sizeof(eleValue));

		XML::UTF_8ToGB2312(svalue, value, lvalue);//编码转换

		sprintf(eleValue, "%s--%s",name, svalue);//拼接叶子节点的节点名称和节点数据

		m_TreeCtrl.InsertItem(eleValue,hCur,TVI_LAST);//返回根项句柄
	}
	else//有子节点
	{
		if(hCur != NULL)
		{
			hRoot = hCur;//父节点狭义
		}
		const char* name = xmlNode->getName();

		if(NULL == hRoot)
		{
			hRoot = m_TreeCtrl.InsertItem(name,TVI_ROOT);//返回根项句柄
			hSave = hRoot; 
		}
		else
		{
			hCur = m_TreeCtrl.InsertItem(name,hRoot, TVI_LAST);
		}

		for(int i = 0; i<nNodes; i++)
		{
			Node* childNode = xmlNode->getNode(i);
			ShowXmlData(childNode);
			if ((i == (nNodes - 1))&&(hSave != hRoot))//当解析到叶子节点且父节点不是根节点
			{
				hCur = m_TreeCtrl.GetParentItem(hCur);
			}
		}
	}  
	return 1;
}


 

 树形控件的基本操作:

    HTREEITEM hRoot,hCur,hSave;//树控制项目句柄     

    m_TreeCtrl.InsertItem(eleValue,hCur,TVI_LAST);//返回根项句柄最重要的就是要确定父节点是谁,也就是第二个参数,五个参数的InsertItem是可以插入图表,如果不插入图表省略两个参数。

要注意的问题:树形控件风格的设定,各项代表的含义是不同的,错误的设置会导致节点数据无法显示的问题       

       DWORD dwStyles = GetWindowLong(m_TreeCtrl.m_hWnd,GWL_STYLE);//获取树控制原风格     dwStyles|=TVS_EDITLABELS|TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT;SetWindowLong(m_TreeCtrl.m_hWnd,GWL_STYLE,dwStyles);//设置风格           

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值