XML解析器示例应用

在开发应用程序时,经常需要使用XML标记语言来存储和传输数据。然而,发现市面上用于辅助快速开始的示例应用程序非常少。平台SDK中的文档和示例似乎都是为Visual Basic/VBScript准备的,而不是为C++/MFC

在这个示例应用程序中,尝试解析一个XML文件,并将其以基本的树状视图形式呈现。代码递归地遍历文档的元素和属性。一些已知的元素类型被赋予了标识图标,一些内容/值也被表达出来。

包含在.zip文件中的第一个XML文件包括一个DTD(文档类型定义)。

图1 - 示例XML解析器对话框

MSXML对象检测到的解析错误会在消息框中显示,并定位XML文档中的问题位置。

图2 - 解析错误报告

查看源代码中的解析器代码——它相当简单。

如果感兴趣,这个文件的长期目标是为应用程序提供可外部配置的toolbar和menu布局定义。由于客户的性质,最终用户定制还不适用,但所期望的规格很可能在离开项目后提出。

为了实现这个XML解析器,使用了C++和MFC(Microsoft Foundation Classes)。MFC是一个应用程序框架,它提供了一组可重用的类库,用于开发Windows应用程序。MSXML是Microsoft XML Parser的简称,它内置于Internet Explorer 4及以上版本中,使用的是IE5。

以下是实现XML解析器的一些关键步骤:

  1. 创建一个MFC应用程序项目。
  2. 在项目中添加一个新的对话框类,用于显示XML树状视图。
  3. 使用MSXML库来解析XML文件。
  4. 递归遍历XML文档的元素和属性。
  5. 为已知元素类型分配标识图标。
  6. 在对话框中显示解析后的XML树状视图
  7. 处理并显示解析错误。

以下是解析XML文件并显示树状视图的示例代码片段:

#include <afxwin.h> #include <msxml.h> class CXMLParserApp : public CWinApp { public: virtual BOOL InitInstance(); }; class CXMLParserDlg : public CDialog { // Construction public: CXMLParserDlg(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CXMLParserDlg) enum { IDD = IDD_XMLPARSER_DIALOG }; CTreeCtrl m_Tree; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CXMLParserDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: HICON m_hIcon; // Generated message map functions //{{AFX_MSG(CXMLParserDlg) virtual BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; BEGIN_MESSAGE_MAP(CXMLParserDlg, CDialog) //{{AFX_MSG_MAP(CXMLParserDlg) ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP END_MESSAGE_MAP() // CXMLParserApp BOOL CXMLParserApp::InitInstance() { CWinApp::InitInstance(); CXMLParserDlg dlg; m_pMainWnd = &dlg; dlg.DoModal(); return FALSE; } // CXMLParserDlg message handlers CXMLParserDlg::CXMLParserDlg(CWnd* pParent /*=NULL*/) : CDialog(CXMLParserDlg::IDD, pParent) { // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here } void CXMLParserDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CXMLParserDlg) DDX_Control(pDX, IDC_TREE, m_Tree); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CXMLParserDlg, CDialog) //{{AFX_MSG_MAP(CXMLParserDlg) ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP END_MESSAGE_MAP() // CXMLParserDlg message handlers BOOL CXMLParserDlg::OnInitDialog() { CDialog::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here return TRUE; // return TRUE unless you set the focus to a control } void CXMLParserDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } HCURSOR CXMLParserDlg::OnQueryDragIcon() { return static_cast(m_hIcon); }

这段代码展示了如何创建一个MFC对话框应用程序,用于解析XML文件并显示树状视图。它使用了MSXML库来解析XML文件,并在对话框中显示解析结果。

在解析XML文件时,可能会遇到各种错误。MSXML对象提供了错误处理机制,可以在解析过程中捕获和处理这些错误。以下是处理解析错误的示例代码片段:

HRESULT hr = S_OK; IXMLDOMParseError *pError = NULL; try { // Load the XML document hr = pXMLDoc->loadXML(bstrXML); if (FAILED(hr)) { // Display error message MessageBox(NULL, _T("Failed to load XML document."), _T("Error"), MB_OK | MB_ICONERROR); } else { // Parse the XML document hr = pXMLDoc->parseError(&pError); if (SUCCEEDED(hr) && pError != NULL) { long line = 0; long linepos = 0; BSTR reason; BSTR srcText; pError->get_line(&line); pError->get_linepos(&linepos); pError->get_reason(&reason); pError->get_srcText(&srcText); CString errorStr; errorStr.Format(_T("Error at line %d, column %d: %s\n%s"), line, linepos, reason, srcText); MessageBox(NULL, errorStr, _T("XML Parse Error"), MB_OK | MB_ICONERROR); } } } catch (...) { MessageBox(NULL, _T("An unexpected error occurred."), _T("Error"), MB_OK | MB_ICONERROR); }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485