我使用expat来读取xml文件。我想从xml文件中指定的配置中填充一些我的类成员变量。我已经定义了我的startelement处理程序,
void Start(void *data,const XML_Char *el, const XML_Char **attr)
,这将引用如下:
XML_SetElementHandler(parser,Start, NULL);
目前我正在使用全局结构g_stConfigInfo
来存储Start()
例如,
void Start(void *data,const XML_Char *el, const XML_Char **attr)
{
if( _tcscmp(el,_T("blah"))==0 )
{
for (int i=0; attr[i]; i+=2)
{
if(_tcscmp(attr[i],_T("name"))==0)
{
g_stConfigInfo.sInputName = attr[i+1];
}
.........
然后我正在做myclass.sInputName = g_stConfigInfo.sInputname
我宁愿不使用全局变量,而是能够使其成为需要填充其成员变量的类的成员函数。 我不想在Start()中有这个类的实例。这样做的最佳方式是什么?
答案 0 :(得分:1)
好吧,类成员函数就像常规函数一样,附加了隐式数据上下文。因此,如果您想避免引用全局数据,那么您必须将非NULL上下文参数传递给Start
。
习惯做法通常是这样的:
class MyHandler {
public:
void Start(const XML_Char *el, const XML_Char **attr) {
// ...dispatch on "el" here.
// e.g. a map of strings to member function pointers
}
};
...
template<T>
void
Start(void *data, const XML_Char *el, const XML_Char **attr)
{
T *handler = static_cast<T*>(data);
handler->Start(el, attr);
}
MyHandler handler;
XML_SetUserData(parser, handler);
XML_SetElementHandler(parser, Start<MyHandler>, NULL);
换句话说,如果你的类对应于某个XML元素,那么将它传递给处理函数是没有错的。
答案 1 :(得分:1)
之前我没有使用过Expat,但我认为使用XML_SetUserData就是你想要的。
class my_data
{
public:
static void start_callback(void *data, const XML_Char *el, const XML_Char **attr)
{
static_cast<my_data*>(data)->start(el, attr);
}
void start(const XML_Char *el, const XML_Char **attr);
};
//...
my_data data;
XML_SetUserData(parser, &data);
XML_SetElementHandler(parser, my_data::start_callback, NULL);
SetUserData将使解析器将您提供给它的指针传递给任何处理程序回调。 http://www.xml.com/pub/a/1999/09/expat/index.html?page=3#setuserdata