lua中如何使用tinyxml

lua中如何使用tinyxml

tinyxml是C++的XML解析器,能够在Windows或Linux中编译。这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这棵XML树。
DOM模型即文档对象模型,是将整个文档分成多个元素(如书、章、节、段等),并利用树型结构表示这些元素之间的顺序关系以及嵌套包含关系。

下面这两个文件就是对tinyxml库中常用的接口在lua的注册封装,使用的是常规的lua注册方法
lua_xml.h
lua_xml.cp
  1 #include <new>
  2 #include <stdlib.h>
  3 #include "luaxml.h"
  4 
  5 extern "C"{
  6 #include <lauxlib.h>
  7 #include <lualib.h>
  8 };
  9 
 10 #include "tinyxml.h"
 11 #include "log.h"
 12 #include "packetcross.h"
 13 #include "filepacket.h"
 14 
 15 #define TINYXML_TABLE_NAME "TiXmlDocument_metatable"
 16 #define XMLELEMENT_TABLE_NAME "TiXmlElement_metatable"
 17 static int lua_tinyxml_new (lua_State *L)
 18 {
 19     TiXmlDocument *doc = (TiXmlDocument *)lua_newuserdata(L, sizeof(TiXmlDocument));
 20     if (!doc)
 21     {
 22         lua_pushnil(L);
 23         return 1;
 24     }
 25     new(doc) TiXmlDocument();
 26     luaL_getmetatable(L, TINYXML_TABLE_NAME);
 27     lua_setmetatable(L, -2);
 28     return 1;
 29 }
 30 
 31 static TiXmlDocument *get_tixml (lua_State *L)
 32 {
 33     TiXmlDocument *doc = (TiXmlDocument *)luaL_checkudata(L, 1, TINYXML_TABLE_NAME);
 34     luaL_argcheck(L, doc != NULL, 1, "TiXmlDocument expected");
 35     return doc;
 36 }
 37 
 38 static int destroy_tixmldocument (lua_State *L)
 39 {
 40     TiXmlDocument *doc = get_tixml(L);
 41     doc->~TiXmlDocument();
 42     return 0;
 43 }
 44 
 45 static int luatixml_loadfile (lua_State *L)
 46 {
 47     TiXmlDocument *doc = get_tixml(L);
 48     const char *filename = luaL_checkstring(L, 2);
 49     luaL_argcheck(L, strcmp(filename, "") != 0, 2, "filename can't for empty");
 50     bool inpacket = luaL_opt(L, lua_toboolean, 3, true);
 51     if (inpacket)
 52     {
 53 #ifdef USE_PACKET
 54         struct packet *datapk = crosspacket_datapacket();
 55         int size = packet_openfile(datapk, filename);
 56         if (size > 0)
 57         {
 58             int buflen = size + 1;
 59             char *buf = (char *)malloc(buflen);
 60             packet_readfile(datapk, buf, size);
 61             buf[size] = 0;
 62             lua_pushboolean(L, doc->LoadFileFromBuffer(buf, buflen));
 63             free(buf);
 64         }
 65         else
 66         {
 67             lua_pushboolean(L, false);
 68         }
 69         return 1;
 70 #endif
 71     }
 72 
 73     lua_pushboolean(L, doc->LoadFile(filename));
 74     return 1;
 75 }
 76 
 77 static int lua_xmlelement_new (lua_State *L, TiXmlElement *el)
 78 {
 79     if (!el)
 80     {
 81         lua_pushnil(L);
 82         return 1;
 83     }
 84     TiXmlElement **point = (TiXmlElement **)lua_newuserdata(L, sizeof(TiXmlElement*));
 85     if (!point)
 86     {
 87         log_error("lua newuserdata failed!");
 88         lua_pushnil(L);
 89         return 1;
 90     }
 91     *point = el;
 92     luaL_getmetatable(L, XMLELEMENT_TABLE_NAME);
 93     lua_setmetatable(L, -2);
 94     return 1;
 95 }
 96 
 97 static int luatixml_firstchildelement (lua_State *L)
 98 {
 99     TiXmlDocument *doc = get_tixml(L);
100     const char *elname = luaL_checkstring(L, 2);
101     TiXmlElement *el = doc->FirstChildElement(elname);
102     lua_xmlelement_new(L, el);
103     return 1;
104 }
105 
106 static int luatixml_savefile (lua_State *L)
107 {
108     TiXmlDocument *doc = get_tixml(L);
109     lua_pushboolean(L, doc->SaveFile());
110     return 1;
111 }
112 
113 static TiXmlElement *get_xml_element (lua_State *L)
114 {
115     TiXmlElement **point = (TiXmlElement **)luaL_checkudata(L, 1, XMLELEMENT_TABLE_NAME);
116     luaL_argcheck(L, (*point) != NULL, 1, "TiXmlElement expected");
117     return *point;
118 }
119 
120 static int lua_xmlelement_firstchildelement (lua_State *L)
121 {
122     TiXmlElement *el = get_xml_element(L);
123     const char *cname = luaL_checkstring(L, 2);
124     TiXmlElement *res = el->FirstChildElement(cname);
125     lua_xmlelement_new(L, res);
126     return 1;
127 }
128 
129 static int lua_xmlelement_nextsiblingelement (lua_State *L)
130 {
131     TiXmlElement *el = get_xml_element(L);
132     const char *nname = luaL_checkstring(L, 2);
133     TiXmlElement *res = el->NextSiblingElement(nname);
134     lua_xmlelement_new(L, res);
135     return 1;
136 }
137 
138 static int lua_xmlelement_querystring (lua_State *L)
139 {
140     TiXmlElement *el = get_xml_element(L);
141     const char *elname = luaL_checkstring(L, 2);
142     const char *vl = el->Attribute(elname);
143     luaL_argcheck(L, vl != NULL, 2, "not find this xml element!");
144     lua_pushstring(L, vl);
145     return 1;
146 }
147 
148 static int lua_xmlelement_queryint (lua_State *L)
149 {
150     TiXmlElement *el = get_xml_element(L);
151     const char *elname = luaL_checkstring(L, 2);
152     int temp = 0;
153     int res = el->QueryIntAttribute(elname, &temp);
154     luaL_argcheck(L, res == TIXML_SUCCESS, 2, "not find this xml element!");
155     lua_pushinteger(L, temp);
156     return 1;
157 }
158 
159 static int lua_xmlelement_querydouble (lua_State *L)
160 {
161     TiXmlElement *el = get_xml_element(L);
162     const char *elname = luaL_checkstring(L, 2);
163     double temp = 0.0f;
164     int res = el->QueryDoubleAttribute(elname, &temp);
165     luaL_argcheck(L, res == TIXML_SUCCESS, 2, "not find this xml element!");
166     lua_pushnumber(L, temp);
167     return 1;
168 }
169 
170 static int lua_xmlelement_setstring (lua_State *L)
171 {
172     TiXmlElement *el = get_xml_element(L);
173     const char *name = luaL_checkstring(L ,2);
174     const char *vl = luaL_checkstring(L, 3);
175     el->SetAttribute(name, vl);
176     return 0;
177 }
178 
179 static int lua_xmlelement_setint (lua_State *L)
180 {
181     TiXmlElement *el = get_xml_element(L);
182     const char *name = luaL_checkstring(L, 2);
183     int temp = luaL_checkinteger(L, 3);
184     el->SetAttribute(name, temp);
185     return 0;
186 }
187 
188 static int lua_xmlelement_setdouble (lua_State *L)
189 {
190     TiXmlElement *el = get_xml_element(L);
191     const char *name = luaL_checkstring(L, 2);
192     double temp = luaL_checknumber(L, 3);
193     el->SetDoubleAttribute(name, temp);
194     return 0;
195 }
196 
197 static const struct luaL_reg element_class_member_functin[] = {
198     {"FirstChildElement", lua_xmlelement_firstchildelement},
199     {"NextSiblingElement", lua_xmlelement_nextsiblingelement},
200     {"QueryString", lua_xmlelement_querystring},
201     {"QueryInt", lua_xmlelement_queryint},
202     {"QueryDouble", lua_xmlelement_querydouble},
203     {"SetString", lua_xmlelement_setstring},
204     {"SetInt", lua_xmlelement_setint},
205     {"SetDouble", lua_xmlelement_setdouble},
206     {0, 0}
207 };
208 
209 static const struct luaL_reg class_member_functin[] = {
210     {"LoadFile", luatixml_loadfile},
211     {"FirstChildElement", luatixml_firstchildelement},
212     {"SaveFile", luatixml_savefile},
213     {0, 0}
214 };
215 
216 static const struct luaL_reg class_static_funciton[] = {
217     {"new", lua_tinyxml_new},
218     {0, 0}
219 };
220 
221 static void lua_tixmlelement_register (lua_State *L)
222 {
223     /*创建元表*/
224     luaL_newmetatable(L, XMLELEMENT_TABLE_NAME);
225 
226     /*查找索引,把它指向metatable自身(因为稍后会在metatable里加入一些成员)*/
227     lua_pushvalue(L, -1);
228     lua_setfield(L, -2, "__index");
229 
230     /*
231     注册此元表的成员(因为当前栈顶为此元表)---也就是成员函数。切记库名为NULL。
232     他等同于一个个设置方法:
233     lua_pushcfunction(L, function);
234     lua_setfield(L, -2, functionn_name_in_lua);
235     */
236     luaL_register(L, NULL, element_class_member_functin);
237 
238     /*弹1个*/
239     lua_pop(L, 1);
240 }
241 
242 static void lua_tixmldocument_register (lua_State *L)
243 {
244     /*创建元表*/
245     luaL_newmetatable(L, TINYXML_TABLE_NAME);
246 
247     /*查找索引,把它指向metatable自身(因为稍后会在metatable里加入一些成员)*/
248     lua_pushvalue(L, -1);
249     lua_setfield(L, -2, "__index");
250 
251     /*元表的gc域*/
252     lua_pushcfunction(L, destroy_tixmldocument);
253     lua_setfield(L, -2, "__gc");
254 
255     /*
256     注册此元表的成员(因为当前栈顶为此元表)---也就是成员函数。切记库名为NULL。
257     他等同于一个个设置方法:
258     lua_pushcfunction(L, function);
259     lua_setfield(L, -2, functionn_name_in_lua);
260     */
261     luaL_register(L, NULL, class_member_functin);
262 
263     /*注册库。切记库名非空,他会创建一个表,若不存在的话,然后把方法列表加入表中。*/
264     luaL_register(L, "tinyxml", class_static_funciton);
265 
266     /*弹2个*/
267     lua_pop(L, 2);
268 }
269 
270 void lua_xml_register (lua_State *L)
271 {
272     lua_tixmlelement_register(L);
273     lua_tixmldocument_register(L);
274 }
275 

 1 #ifndef _H_LUA_XML_H_
 2 #define _H_LUA_XML_H_
 3 
 4 #ifdef __cplusplus
 5 extern "C"{
 6 #endif
 7 
 8 #include <lua.h>
 9 
10 #ifdef __cplusplus
11 };
12 #endif
13 
14 void lua_xml_register (lua_State *L);
15 
16 #endif
17 
示例(lua文件):
function testxml()
xml = tinyxml();
filename = "./data/logiclist.xml";
if not xml:LoadFile(filename) then
print("open ", filename, " failed!");
return;
end
firstelename = "logicinfo";
element = xml:FirstChildElement(firstelename);
if not element then
print("not find element, element:", firstelename);
return;
end
print("servergroupid:", element:QueryString("servergroupid"));
firstelename = "logicserver";
otel = element:FirstChildElement(firstelename);
while otel do
print("ip:", otel:QueryString("ip"), "port:", otel:QueryInt("port"));
otel = otel:NextSiblingElement(firstelename);
end
return true;
end
下面的两个文件是使用lua_tinker对tinyxml库的封装
lua_class.h
lua_class.cpp

 1 #ifndef luaclass_h
 2 #define luaclass_h
 3 
 4 #include "tinyxml.h"
 5 
 6 class _TiXmlAttribute:public TiXmlAttribute
 7 {
 8 public:
 9     _TiXmlAttribute* _TiXmlAttribute::Next();
10 };
11 
12 class _TiXmlElement:public TiXmlElement
13 {
14 public:
15     int QueryInt( const char* name) const;
16     double QueryDouble( const char* name) const;
17     _TiXmlElement* FirstChildElement( const char * _value );
18     _TiXmlElement* FirstChild();
19     _TiXmlElement* NextSiblingElement( const char *_next ) ;
20     _TiXmlAttribute* FirstAttribute();
21     _TiXmlElement* NextSibling();
22 };
23 
24 class _TiXmlDocument:public TiXmlDocument
25 {
26 public:
27     bool LoadFile( const char* _filename, TiXmlEncoding encoding );
28     _TiXmlElement* FirstChildElement( const char * _value );
29         _TiXmlElement* RootElement();
30     
31     _TiXmlElement* FirstChild();
32 };
33 
34 
35 
36 
注册代码:

 1 #ifndef register_h
 2 #define register_h
 3 #include "luaclass.h"
 4 #include "lua_tinker.h"
 5 
 6 bool regxml(lua_State* L)
 7 {
 8     //_TiXmlAttribute
 9     lua_tinker::class_add<_TiXmlAttribute>(L,"tinyatr");
10     lua_tinker::class_def<_TiXmlAttribute>(L,"Name",&_TiXmlAttribute::Name);
11     lua_tinker::class_def<_TiXmlAttribute>(L,"Value",&_TiXmlAttribute::Value);
12     lua_tinker::class_def<_TiXmlAttribute>(L,"IntValue",&_TiXmlAttribute::IntValue);
13     _TiXmlAttribute* (_TiXmlAttribute::*ptr0)() = &_TiXmlAttribute::Next;
14     lua_tinker::class_def<_TiXmlAttribute>(L,"Next",&_TiXmlAttribute::Next);
15 
16     //_TiXmlElement
17     lua_tinker::class_add<_TiXmlElement>(L,"tinyelm");
18     lua_tinker::class_con<_TiXmlElement>(L,lua_tinker::constructor<_TiXmlElement,const _TiXmlElement&>);
19     _TiXmlElement* (_TiXmlElement::*ptr1)( const char *) = &_TiXmlElement::FirstChildElement;
20     lua_tinker::class_def<_TiXmlElement>(L,"FirstChildElement",ptr1);
21     _TiXmlElement* (_TiXmlElement::*ptr2)( const char *) = &_TiXmlElement::NextSiblingElement;
22     lua_tinker::class_def<_TiXmlElement>(L,"NextSiblingElement",ptr2);
23     const char* (_TiXmlElement::*ptr3)( const char* ) const = &_TiXmlElement::Attribute;
24     lua_tinker::class_def<_TiXmlElement>(L,"QueryString",ptr3);
25 
26     lua_tinker::class_def<_TiXmlElement>(L,"QueryInt",&_TiXmlElement::QueryInt);
27     lua_tinker::class_def<_TiXmlElement>(L,"QueryDouble",&_TiXmlElement::QueryDouble);
28 
29     void (_TiXmlElement::*ptr4)( const char*, const char * ) = &_TiXmlElement::SetAttribute;
30     lua_tinker::class_def<_TiXmlElement>(L,"SetString",ptr4);
31 
32     //新增
33     lua_tinker::class_def<_TiXmlElement>(L,"Value",&_TiXmlElement::Value);
34 
35 
36     _TiXmlElement* (_TiXmlElement::*ptr9)() = &_TiXmlElement::FirstChild;
37     lua_tinker::class_def<_TiXmlElement>(L,"FirstChild",ptr9);
38 
39 
40     _TiXmlElement* (_TiXmlElement::*ptr10)() = &_TiXmlElement::NextSibling;
41     lua_tinker::class_def<_TiXmlElement>(L,"NextSibling",ptr10);
42 
43 
44 
45 
46     lua_tinker::class_def<_TiXmlElement>(L,"SetInt",&_TiXmlElement::SetDoubleAttribute);
47     lua_tinker::class_def<_TiXmlElement>(L,"SetDouble",&_TiXmlElement::SetDoubleAttribute);
48     lua_tinker::class_def<_TiXmlElement>(L,"GetText",&_TiXmlElement::GetText);
49 
50     _TiXmlAttribute* (_TiXmlElement::*ptr7)() = &_TiXmlElement::FirstAttribute;
51     lua_tinker::class_def<_TiXmlElement>(L,"FirstAttribute",ptr7);
52 
53 
54     //_TiXmlDocument
55     lua_tinker::class_add<_TiXmlDocument>(L,"tinyxml");
56     lua_tinker::class_con<_TiXmlDocument>(L,lua_tinker::constructor<_TiXmlDocument>);
57     lua_tinker::class_def<_TiXmlDocument>(L,"LoadFile",&_TiXmlDocument::LoadFile);
58 
59     _TiXmlElement* (_TiXmlDocument::*ptr5)( const char * ) = &_TiXmlDocument::FirstChildElement;
60     lua_tinker::class_def<_TiXmlDocument>(L,"FirstChildElement",ptr5);
61 
62     bool (_TiXmlDocument::*ptr6)() const = &_TiXmlDocument::SaveFile;
63     lua_tinker::class_def<_TiXmlDocument>(L,"SaveFile",ptr6);
64 
65     _TiXmlElement* (_TiXmlDocument::*ptr8)() = &_TiXmlDocument::RootElement;
66     lua_tinker::class_def<_TiXmlDocument>(L,"RootElement",ptr8);
67 
68 
69     return true;
70 }
71 
72 
73 
74 
注意的是lua_tinker直接不支持c++重载,lua的底层是c,在c里面可以用函数指针实现多态,在lua中使用c++的类的成员,要用:,而不是.。
示例:
local function LoadLevelBase(filename)
xml = tinyxml();
if not xml:LoadFile(filename) then
print("open "..filename.." failed!");
end
local rootElement=xml:RootElement();
local element = rootElement:FirstChildElement("element");
local att_Name;
local att_Value;
--遍历xml
while element do
local ChildElement=element:FirstChild();
local ele={};
local attri={};
local event={};
--子节点
while ChildElement do
ele_Name=ChildElement:Value();
if ele_Name=='Event' then
attr = ChildElement:FirstAttribute();
while attr do
att_Name  = attr:Name();
att_Value = attr:Value();
attr = attr:Next();
end
else
ele_Value=ChildElement:GetText();
if ele_Name ~= 'Name' then
ele_Value=tonumber(ele_Value);
end
ele[ele_Name]=ele_Value;
--读取元素
-print(ele_Name..'='..ele_Value);
end
ChildElement=ChildElement:NextSibling();
end
end
end



你可能感兴趣的:(lua中如何使用tinyxml)