这几天刚接到一个任务:要将xml配置文件转成可以直接读写的lua文件,方便在lua程序中直接调用,废话不多说直接上代码
(xmZMlua.lua文件)
saveDirPath = "/xxx/" --- 保存转好的lua文件路劲(其中xxx代表的是路径,下同)
xmlDirPath = "/xxx/" --- 待转的xml文件路径
require "lfs"
function SaveTableContent(file, obj)
local szType = type(obj);
if szType == "number" then
file:write(obj);
elseif szType == "string" then
file:write(string.format("%q", obj));
elseif szType == "table" then
--把table的内容格式化写入文件
-- print(obj.nodeFlag)
if obj.nodeFlag ~= nil then
if obj:numProperties() == 0 and obj:numChildren() == 0 then
SaveTableContent(file, obj:value() or "");
else
file:write("{");
if obj:numProperties() ~= 0 then
-- print(obj)
file:write("[\"$\"]={");
local pTable = {}
local properties = obj:properties()
for i=1, #properties do
local propertie = properties[i]
local propertieName = propertie.name
local propertieValue = propertie.value
-- print("")
file:write("[");
SaveTableContent(file, propertieName);
file:write("]=");
SaveTableContent(file, propertieValue);
if i ~= #properties then file:write(", ") end
end
file:write("}");
if obj:numChildren() ~= 0 then file:write(",") end
end
if obj:numChildren() ~= 0 then
-- print("numChildren:"..tostring(obj:numChildren()))
local allChildrenTable = {}
local children = obj:children()
local nextChildName = ""
local lastChildName = ""
for i=1,obj:numChildren() do
local child = children[i]
nextChildName = child:name()
-- print("lastChildName1-----------:"..lastChildName)
if nextChildName ~= lastChildName then
-- print("lastChildName2-----------:"..lastChildName)
allChildrenTable[nextChildName] = {}
lastChildName = nextChildName
-- print("lastChildName4-----------:"..lastChildName)
end
table.insert(allChildrenTable[nextChildName], child)
end
for i,v in pairs(allChildrenTable) do
file:write("[");
SaveTableContent(file, i);
file:write("]=");
SaveTableContent(file, v);
file:write(", ");
-- print("key:"..i..#v)
end
-- SaveTableContent(file, allChildrenTable, fileName);
end
file:write("}");
end
else
file:write("{");
for i, v in pairs(obj) do
local vType = type(v)
if vType ~= "function" then
file:write("[");
SaveTableContent(file, i);
file:write("]=");
SaveTableContent(file, v );
file:write(", ");
end
end
file:write("}");
end
else
-- error("can't serialize a "..szType);
end
end
function SaveTable(fileName,obj)
-- print(path);
-- printLog();
local fileNewName = string.gsub(fileName, ".xml", ".lua");
local savePath = saveDirPath..fileNewName
local file = io.open(savePath, "w");
file:write("local "..string.gsub(fileName, ".xml", "").." = \n");
-- print(fileName);
SaveTableContent(file, obj);
file:write("\nreturn "..string.gsub(fileName, ".xml", "") );
file:close();
end
function newParser()
XmlParser = {};
function XmlParser:ToXmlString(value)
value = string.gsub(value, "&", "&"); -- '&' -> "&"
value = string.gsub(value, "<", "<"); -- '<' -> "<"
value = string.gsub(value, ">", ">"); -- '>' -> ">"
value = string.gsub(value, "\"", """); -- '"' -> """
value = string.gsub(value, "([^%w%&%;%p%\t% ])",
function(c)
print("c::::------->>>>>"..string.byte(c))
return string.format("&#x%X;", string.byte(c))
end);
return value;
end
function XmlParser:FromXmlString(value)
value = string.gsub(value, "&#x([%x]+)%;",
function(h)
print("h::::------->>>>>"..string.char(tonumber(h, 16)))
return string.char(tonumber(h, 16))
end);
value = string.gsub(value, "&#([0-9]+)%;",
function(h)
print("h::::------->>>>>"..string.char(tonumber(h, 10)))
return string.char(tonumber(h, 10))
end);
value = string.gsub(value, """, "\"");
value = string.gsub(value, "'", "'");
value = string.gsub(value, ">", ">");
value = string.gsub(value, "<", "<");
value = string.gsub(value, "&", "&");
return value;
end
function XmlParser:ParseArgs(node, s)
string.gsub(s, "(%w+)=([\"'])(.-)%2", function(w, _, a)
node:addProperty(w, self:FromXmlString(a))
end)
end
function XmlParser:ParseXmlText(xmlText)
local stack = {}
local top = newNode()
table.insert(stack, top)
local ni, c, label, xarg, empty
local i, j = 1, 1
while true do
ni, j, c, label, xarg, empty = string.find(xmlText, "<(%/?)([%w_:]+)(.-)(%/?)>", i)
if not ni then break end
local text = string.sub(xmlText, i, ni - 1);
if not string.find(text, "^%s*$") then
local lVal = (top:value() or "") .. self:FromXmlString(text)
stack[#stack]:setValue(lVal)
end
if empty == "/" then -- empty element tag
local lNode = newNode(label)
self:ParseArgs(lNode, xarg)
top:addChild(lNode)
elseif c == "" then -- start tag
local lNode = newNode(label)
self:ParseArgs(lNode, xarg)
table.insert(stack, lNode)
top = lNode
else -- end tag
local toclose = table.remove(stack) -- remove top
top = stack[#stack]
if #stack < 1 then
error("XmlParser: nothing to close with " .. label)
end
if toclose:name() ~= label then
error("XmlParser: trying to close " .. toclose.name .. " with " .. label)
end
top:addChild(toclose)
end
i = j + 1
end
local text = string.sub(xmlText, i);
if #stack > 1 then
error("XmlParser: unclosed " .. stack[#stack]:name())
end
return top
end
function XmlParser:loadFile(xmlFilename, base)
if not base then
base = system.ResourceDirectory
end
local path = system.pathForFile(xmlFilename, base)
local hFile, err = io.open(path, "r");
if hFile and not err then
local xmlText = hFile:read("*a"); -- read file content
io.close(hFile);
return self:ParseXmlText(xmlText), nil;
else
print(err)
return nil
end
end
return XmlParser
end
function newNode(name)
local node = {}
node.___nodeFlag = true
node.___value = nil
node.___name = name
node.___children = {}
node.___props = {}
function node:nodeFlag() return self.___nodeFlag end
function node:value() return self.___value end
function node:setValue(val) self.___value = val end
function node:name() return self.___name end
function node:setName(name) self.___name = name end
function node:children() return self.___children end
function node:numChildren() return #self.___children end
function node:addChild(child)
if self[child:name()] ~= nil then
if type(self[child:name()].name) == "function" then
local tempTable = {}
table.insert(tempTable, self[child:name()])
self[child:name()] = tempTable
end
table.insert(self[child:name()], child)
else
self[child:name()] = child
end
table.insert(self.___children, child)
end
function node:properties() return self.___props end
function node:numProperties() return #self.___props end
function node:addProperty(name, value)
local lName = "@" .. name
if self[lName] ~= nil then
if type(self[lName]) == "string" then
local tempTable = {}
table.insert(tempTable, self[lName])
self[lName] = tempTable
end
table.insert(self[lName], value)
else
self[lName] = value
end
table.insert(self.___props, { name = name, value = value })
end
return node
end
function getpathes(rootpath, pathes)
pathes = pathes or {}
ret, files, iter = pcall(lfs.dir, rootpath)
if ret == false then
return pathes
end
for entry in files, iter do
local next = false
if entry ~= '.' and entry ~= '..' then
local path = rootpath .. entry
-- print (path)
local attr = lfs.attributes(path)
if attr == nil then
next = true
end
if next == false then
if attr.mode == 'directory' then
getpathes(path, pathes)
else
--进行数据组织
i, j =string.find(path,"%.xml")
if i ~= nil then
local hFile, err = io.open(path, "r");
if hFile and not err then
local xmlText = hFile:read("*a"); -- read file content
io.close(hFile);
-- xmlText = string.gsub(xmlText, "<?xml version=\"1.0\" encoding=\"utf-8\"?>", "")
xmlText = string.gsub(xmlText, "<!%-%-(.-)%-%->", "")
-- print("xmlText:"..xmlText)
local textObj = parser.ParseXmlText(parser, xmlText)
SaveTable(entry, textObj);
--local flag = true
--for i,v in ipairs(exclude2MapArr) do
-- if v == string.gsub(entry, ".xml", "") then
-- flag = false
-- break
-- end
--end
--if flag then createSimpleXml(entry , dofile(saveDirPath..string.gsub(entry, ".xml", ".lua"))); end
print(entry.."-------------------->"..string.gsub(entry, ".xml", ".lua"))
-- return xmlSimple.ParseXmlText(xmlText), nil;
end
end
end
end
end
next = false
end
return pathes
end
-- function createSimpleXml(entry, obj)
-- -- name = name.split('_')[0];
-- local name = string.upper(string.sub(entry, 1, 1))..string.sub(entry, 2, string.len(entry));
-- name = string.gsub(name, ".xml", "")
-- -- print('data[name]:'..obj[name..'s']..'----------------');
-- local arr = obj[name..'s'][1][name];
-- local map = {};
-- print('===========[ '..name..' ] ==========');
-- if name == 'Lang' then
-- for i=1,#arr do
-- map[tostring(arr[i]['$']['key'])] = arr[i];
-- end
-- else
-- for i=1,#arr do
-- map[tostring(arr[i]['$']['id'])] = arr[i];
-- end
-- end
-- SaveTable(entry, map);
-- -- return map;
-- end
if lfs == nil then return end
pathes = {}
parser = newParser()
getpathes(xmlDirPath, pathes)
这其中应用到了“lfs”依赖库,它的全名是“luafilesystem”;要安装它分两步
1)首先必须安装“lua的模块安装部署工具——luaRocks”
2)用luaRocks安装luafilesystem;打开终端,在终端执行命令:luarocks install luafilesystem 这样就部署成功了
本文相关代码借鉴Lua-Simple-XML-Parser中的xmlSimple
注:第一次写博客,不足之处请见谅
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/10562.html