找了好久,很遗憾的发现wxWidget没有提供很好的XML文件解析类,只好自己写一个了,主要用来获取xml节点及读取节点的值,已经够自己用了。废话不多说,直接上代码了。
头文件:
#ifndef WXXMLHELPER_H
#define WXXMLHELPER_H
#pragma once
#include <wx/xml/xml.h>
#include <wx/list.h>
class wxXmlHelper
{
public:
wxXmlHelper(void);
~wxXmlHelper(void);
/**
* @brief 加载XML文件.
* @param sFilePath [in]文件路径.
* @return True or False.
* @remarks
* @author Zhengwen.Fu
* @history - 1.Created by Zhengwen.Fu on 25th Mar,2015.
*/
bool Load(const wxString sFilePath);
/**
* @brief 获取xml节点的内容.
* @param sXPath [in]节点路径.
* @return Content of node or empty string for failed.
* @code
wxXmlHelper h;
h.Load("Order.xml");
wxString s = h.GetContent("/Order/InputParameter/Mod4FilePath");
* @endcode
* @remarks
* @author Zhengwen.Fu
* @history - 1.Created by Zhengwen.Fu on 25th Mar,2015.
*/
wxString GetContent(const wxString sXPath);
/**
* @brief 获取xml节点的内容.
* @param pNode [in]搜索起始节点.
* @param sXPath [in]节点路径.
* @code
wxXmlHelper h;
h.Load("Order.xml");
wxString s = h.GetContent(h.GetRoot(),"/Order/InputParameter/InputFile");
* @endcode
* @return Content of node or empty string for failed.
* @remarks sXPath使用"/"分隔各节点的名称,并且应该包含当前节点的名称.
* @author Zhengwen.Fu
* @history - 1.Created by Zhengwen.Fu on 25th Mar,2015.
*/
wxString GetContent(wxXmlNode *pNode,wxString sXPath);
/**
* @brief 获取xml节点的内容.
* @param sXPath [in]节点路径.
* @param sProName [in]属性名称.
* @return Property of node or empty string for failed.
* @code
wxXmlHelper h;
h.Load("Order.xml");
s = h.GetProperty("/Order/InputParameter/InputFile","id");
* @endcode
* @remarks sXPath使用"/"分隔各节点的名称,并且应该包含当前节点的名称.
* @author Zhengwen.Fu
* @history - 1.Created by Zhengwen.Fu on 25th Mar,2015.
*/
wxString GetProperty(const wxString sXPath,const wxString sProName);
/**
* @brief 获取xml节点的内容.
* @param pNode [in]搜索起始节点.
* @param sXPath [in]节点路径.
* @param sProName [in]属性名称.
* @code
wxXmlHelper h;
h.Load("Order.xml");
wxString s = h.GetProperty(h.GetRoot(),"/Order/InputParameter/InputFile","id");
* @endcode
* @return Property of node or empty string for failed.
* @remarks sXPath使用"/"分隔各节点的名称,并且应该包含当前节点的名称.
* @author Zhengwen.Fu
* @history - 1.Created by Zhengwen.Fu on 25th Mar,2015.
*/
wxString GetProperty(wxXmlNode *pNode,wxString sXPath,const wxString sProName);
/**
* @brief 获取xml文档的根节点.
* @return Node or Null for failed.
* @remarks
* @author Zhengwen.Fu
* @history - 1.Created by Zhengwen.Fu on 25th Mar,2015.
*/
wxXmlNode *GetRoot();
/**
* @brief 获取xml节点.
* @param pNode [in]搜索起始节点.
* @param sXPath [in]节点路径.
* @return Node or Null for failed.
* @code
wxXmlHelper h;
h.Load("Order.xml");
wxXmlNode* node = h.GetNode(h.GetRoot(),"/Order/InputParameter/InputFile");
* @endcode
* @remarks sXPath使用"/"分隔各节点的名称,并且应该包含当前节点的名称.
* @author Zhengwen.Fu
* @history - 1.Created by Zhengwen.Fu on 25th Mar,2015.
*/
wxXmlNode *GetNode(wxXmlNode *pNode,wxString sXPath);
/**
* @brief 查找制定路径下的所有节点.
* @param pNode [in]搜索起始节点.
* @param sXPath [in]节点路径.
* @remarks
Use like this:
* @code
wxXmlHelper h;
h.Load("Order.xml");
wxList *lst = h.GetNodes(h.GetRoot(),"/Order/InputParameter/InputFile");
wxList::iterator it = lst->begin(),end = lst->end();
while(it!=end)
{
wxXmlNode *node = (wxXmlNode*)(*it);
wxString s = node->GetName();
wxPrintf(_T("name = %s id = %s \n"),s,node->GetPropVal("id",""));
++it;
}
delete lst;
//
//Or use
wxList::compatibility_iterator it = lst->GetFirst();
while(it)
{
wxXmlNode *node = (wxXmlNode*)(it->GetData());
wxString s = node->GetName();
wxPrintf(_T("name = %s id = %s \n"),s,node->GetPropVal("id",""));
it = it->GetNext();
}
* @endcode
* @author Zhengwen.Fu
* @history - 1.Created by Zhengwen.Fu on 25th Mar,2015.
*/
wxList *GetNodes(wxXmlNode *pNode,wxString sXPath);
private:
wxXmlDocument m_Doc;
};
#endif
源文件:
#include "wxXmlHelper.h"
#include <wx/arrstr.h>
#include <wx/dynarray.h>
wxXmlHelper::wxXmlHelper(void)
{
}
wxXmlHelper::~wxXmlHelper(void)
{
}
bool wxXmlHelper::Load(const wxString sFilePath)
{
return m_Doc.Load(sFilePath);
}
wxString wxXmlHelper::GetContent(const wxString sXPath)
{
return GetContent(m_Doc.GetRoot(),sXPath);
}
wxString wxXmlHelper::GetContent(wxXmlNode *pNode,wxString sXPath)
{
wxXmlNode *node = GetNode(pNode,sXPath);
if(node)
return node->GetChildren()->GetContent();
else return "";
}
wxString wxXmlHelper::GetProperty(const wxString sXPath,const wxString sProName)
{
return GetProperty(m_Doc.GetRoot(),sXPath,sProName);
}
wxString wxXmlHelper::GetProperty(wxXmlNode *pNode,wxString sXPath,const wxString sProName)
{
wxXmlNode *node = GetNode(pNode,sXPath);
if(node)
return node->GetPropVal(sProName,"");
else return "";
}
wxXmlNode *wxXmlHelper::GetRoot()
{
return m_Doc.GetRoot();
}
wxXmlNode *wxXmlHelper::GetNode(wxXmlNode *pNode,wxString sXPath)
{
if(!pNode)
return NULL;
int pos = sXPath.Find("/");
if(pos==0)
{
sXPath = sXPath.substr(1);
return GetNode(pNode,sXPath);
}
if(pos==wxString::npos)
{
if (pNode->GetName()==sXPath)
return pNode;
else
return GetNode(pNode->GetNext(),sXPath);
}
wxString s = sXPath.substr(0,pos);
sXPath = sXPath.substr(pos+1);
while(pNode && pNode->GetName() != s)
pNode = pNode->GetNext();
return GetNode(pNode->GetChildren(),sXPath);
}
wxList *wxXmlHelper::GetNodes(wxXmlNode *pNode,wxString sXPath)
{
wxList *list = new wxList();
int pos = sXPath.find_last_of(_T('/'));
wxString sName = sXPath.substr(pos+1);
wxXmlNode *node = GetNode(pNode,sXPath);
while(node)
{
if(node->GetName()==sName)
list->Append(reinterpret_cast<wxObject*>(node));
node = node->GetNext();
}
return list;
}
下面是试验时用到的xml文件:
<?xml version="1.0" encoding="utf-8"?>
<Order>
<InputParameter>
<InputFile id="001">../testdata/input/20070512_TM_rad.img</InputFile>
<InputFile id="002">../testdata/input/20070512_TM_rad.img</InputFile>
<InputFile id="003">../testdata/input/20070512_TM_rad.img</InputFile>
<InputFile id="004">../testdata/input/20070512_TM_rad.img</InputFile>
<Mod4FilePath>../testdata/input/Mod4.hdf</Mod4FilePath>
</InputParameter>
<OutputParameter>
<OutputFile>../testdata/output/20070512_TM_Ref.img</OutputFile>
</OutputParameter>
</Order>