Lxp 树 |
|
以下实现从字符串或文件构建一个 XmlTree。 此代码是 LazyKit 的一部分。 实现依赖于 LuaExpat?,一个 expat 绑定。
返回从字符串 s
解析的 XML 树。
返回从 file
完全解析的树。 如果 file
是一个字符串,它被解释为一个文件名并打开;否则,file
被视为一个 io 库文件对象。
请注意,file
被读取并解析为一个大块,因此在 2G 文件上运行它可能不是一个好主意。 另一方面,构建一个 2G 文件的树将是一个更糟糕的想法。
require "lxp" local Public = {} lxptree = Public local tinsert=table.insert local tremove=table.remove local function top(l) return l[table.getn(l)] end local function nukenumeric(t) for i=1,table.getn(t) do t[i] = nil end end local function makeParser() local stack = {{}, n=1} local self = {} local callbacks = {} function callbacks.StartElement(parser, elementName, attributes) local t = {name=elementName} if attributes and attributes[1] then nukenumeric(attributes) t.attr=attributes end tinsert(top(stack), t) tinsert(stack, t) end function callbacks.EndElement(parser, elementName) tremove(stack, t) end function callbacks.CharacterData(parser, string) tinsert(top(stack), string) end local parser = lxp.new(callbacks) function self:parse(s) local result, msg, line, col, pos = parser:parse(s) if result then result, msg, line, col, pos = parser:parse() end if not result then error("expat parse error "..msg.." at line "..line.." column "..col) end parser:close() return stack[1][1] end return self end local function parsestring(s) local p = makeParser() return p:parse(s) end Public.parsestring = parsestring local function wholeFile(filename) local f = assert(io.open(filename)) local s = f:read("*a") assert(f:close()) return s end local function parsefile(f) local s if type(f) == "string" then f = assert(io.open(f)) s = f:read("*a") assert(f:close()) else s = f:read("*a") end return parsestring(s) end Public.parsefile = parsefile return Public