Skip to content

Commit

Permalink
xml库完善
Browse files Browse the repository at this point in the history
  • Loading branch information
xiyoo0812 committed May 7, 2024
1 parent 4bb66a3 commit 917b88e
Showing 1 changed file with 97 additions and 49 deletions.
146 changes: 97 additions & 49 deletions extend/luaxml/src/luaxml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,25 @@
using namespace tinyxml2;

namespace luaxml {
void push_elems2lua(lua_State* L, const XMLElement* elem);

static void push_elem2lua(lua_State* L, const XMLElement* elem) {
uint32_t count = elem->ChildElementCount();
const XMLAttribute* attr = elem->FirstAttribute();
const char* value = elem->GetText();
if (count == 0 && attr == nullptr) {
value = value ? value : "";
if (lua_stringtonumber(L, value) == 0) {
lua_pushstring(L, value);
}
return;
}
lua_createtable(L, 0, 4);
lua_pushstring(L, elem->Name());
lua_setfield(L, -2, "tag");
if (elem->GetText()) {
if (lua_stringtonumber(L, elem->GetText()) == 0) {
lua_pushstring(L, elem->GetText());
if (value) {
if (lua_stringtonumber(L, value) == 0) {
lua_pushstring(L, value);
}
lua_setfield(L, -2, "text");
lua_setfield(L, -2, "_val");
}
const XMLAttribute* attr = elem->FirstAttribute();
if (attr) {
lua_createtable(L, 0, 4);
while (attr) {
Expand All @@ -28,56 +34,87 @@ namespace luaxml {
lua_setfield(L, -2, attr->Name());
attr = attr->Next();
}
lua_setfield(L, -2, "attrs");
lua_setfield(L, -2, "_attr");
}
const XMLElement* child = elem->FirstChildElement();
if (child) {
push_elems2lua(L, child);
lua_setfield(L, -2, "elems");
if (count > 0) {
const XMLElement* child = elem->FirstChildElement();
std::map<std::string, std::vector<const XMLElement*>> elems;
while (child) {
auto it = elems.find(child->Name());
if (it != elems.end()) {
it->second.push_back(child);
} else {
elems.insert(std::make_pair(child->Name(), std::vector{ child }));
}
child = child->NextSiblingElement();
}
for (auto it : elems) {
size_t child_size = it.second.size();
if (child_size == 1) {
push_elem2lua(L, it.second[0]);
} else {
lua_createtable(L, 0, 4);
for (int i = 0; i < child_size; ++i) {
push_elem2lua(L, it.second[i]);
lua_seti(L, -2, i + 1);
}
}
lua_setfield(L, -2, it.first.c_str());
}
}
}

static void push_elems2lua(lua_State* L, const XMLElement* elem) {
int index = 1;
lua_createtable(L, 0, 4);
while (elem) {
push_elem2lua(L, elem);
lua_seti(L, -2, index++);
elem = elem->NextSiblingElement();
static void load_elem4lua(lua_State* L, XMLPrinter* printer);
static void load_table4lua(lua_State* L, XMLPrinter* printer) {
luakit::lua_guard g(L);
if (lua_getfield(L, -1, "_attr") == LUA_TTABLE) {
lua_pushnil(L);
while (lua_next(L, -2) != 0) {
const char* key = lua_tostring(L, -2);
switch (lua_type(L, -1)) {
case LUA_TSTRING: printer->PushAttribute(key, lua_tostring(L, -1)); break;
case LUA_TBOOLEAN: printer->PushAttribute(key, lua_toboolean(L, -1)); break;
case LUA_TNUMBER: lua_isinteger(L, -1) ? printer->PushAttribute(key, lua_tointeger(L, -1)) : printer->PushAttribute(key, lua_tonumber(L, -1)); break;
}
lua_pop(L, 1);
}
}
switch (lua_getfield(L, -2, "_val")) {
case LUA_TSTRING: printer->PushText(lua_tostring(L, -1)); break;
case LUA_TBOOLEAN: printer->PushText(lua_toboolean(L, -1)); break;
case LUA_TNUMBER: lua_isinteger(L, -1) ? printer->PushText(lua_tointeger(L, -1)) : printer->PushText(lua_tonumber(L, -1)); break;
}
lua_pushnil(L);
while (lua_next(L, -4) != 0) {
const char* key = lua_tostring(L, -2);
if (strcmp(key, "_attr") != 0 && strcmp(key, "_val") != 0) {
load_elem4lua(L, printer);
}
lua_pop(L, 1);
}
}

static void load_elem4lua(lua_State* L, XMLPrinter* printer) {
luakit::lua_guard g(L);
if (lua_getfield(L, -1, "tag") == LUA_TSTRING) {
printer->OpenElement(lua_tostring(L, -1));
if (lua_getfield(L, -2, "attrs") == LUA_TTABLE) {
lua_pushnil(L);
while (lua_next(L, -2) != 0) {
const char* key = lua_tostring(L, -2);
switch (lua_type(L, -1)) {
case LUA_TBOOLEAN: printer->PushAttribute(key, lua_toboolean(L, -1)); break;
case LUA_TSTRING: printer->PushAttribute(key, lua_tostring(L, -1)); break;
case LUA_TNUMBER: lua_isinteger(L, -1) ? printer->PushAttribute(key, lua_tointeger(L, -1)) : printer->PushAttribute(key, lua_tonumber(L, -1)); break;
}
lua_pop(L, 1);
}
}
switch (lua_getfield(L, -3, "text")) {
case LUA_TBOOLEAN: printer->PushText(lua_toboolean(L, -1)); break;
int type = lua_type(L, -1);
const char* key = lua_tostring(L, -2);
size_t raw_len = (type == LUA_TTABLE) ? lua_rawlen(L, -1) : 0;
if (raw_len == 0) {
printer->OpenElement(key);
switch (type) {
case LUA_TTABLE: load_table4lua(L, printer); break;
case LUA_TSTRING: printer->PushText(lua_tostring(L, -1)); break;
case LUA_TBOOLEAN: printer->PushText(lua_toboolean(L, -1)); break;
case LUA_TNUMBER: lua_isinteger(L, -1) ? printer->PushText(lua_tointeger(L, -1)) : printer->PushText(lua_tonumber(L, -1)); break;
}
if (lua_getfield(L, -4, "elems") == LUA_TTABLE) {
size_t raw_len = lua_rawlen(L, -1);
for (int i = 1; i <= raw_len; ++i) {
lua_rawgeti(L, -1, i);
load_elem4lua(L, printer);
lua_pop(L, 1);
}
}
printer->CloseElement();
return;
}
lua_pushstring(L, key);
for (int i = 1; i <= raw_len; ++i) {
lua_rawgeti(L, -2, i);
load_elem4lua(L, printer);
lua_pop(L, 1);
}
lua_pop(L, 1);
}

static int decode_xml(lua_State* L, const char* xml) {
Expand All @@ -87,14 +124,21 @@ namespace luaxml {
lua_pushstring(L, "parse xml doc failed!");
return 2;
}
push_elem2lua(L, doc.RootElement());
lua_createtable(L, 0, 4);
const XMLElement* root = doc.RootElement();
push_elem2lua(L, root);
lua_setfield(L, -2, root->Name());
return 1;
}

static int encode_xml(lua_State* L) {
XMLPrinter printer;
printer.PushHeader(false, true);
load_elem4lua(L, &printer);
lua_pushnil(L);
while (lua_next(L, -2) != 0) {
load_elem4lua(L, &printer);
lua_pop(L, 1);
}
lua_pushlstring(L, printer.CStr(), printer.CStrSize());
return 1;
}
Expand Down Expand Up @@ -130,7 +174,11 @@ namespace luaxml {
}
XMLPrinter printer(fp);
printer.PushHeader(false, true);
load_elem4lua(L, &printer);
lua_pushnil(L);
while (lua_next(L, -2) != 0) {
load_elem4lua(L, &printer);
lua_pop(L, 1);
}
lua_pushboolean(L, true);
fclose(fp);
return 1;
Expand Down

0 comments on commit 917b88e

Please sign in to comment.