diff --git a/jls/util/XmlParser-XmlParser.lua b/jls/util/XmlParser-XmlParser.lua new file mode 100644 index 0000000..e99a2a5 --- /dev/null +++ b/jls/util/XmlParser-XmlParser.lua @@ -0,0 +1,25 @@ +local XmlParser = require('XmlParser') -- xml2lua parser + +local function errorHandler(errMsg, pos) + error(string.format("%s [char=%d]\n", errMsg or "Parse Error", pos)) +end + +local function starttag(handler, tag) + handler:startElement(tag.name, tag.attrs) +end + +local function endtag(handler, tag) + handler:endElement(tag.name) +end + +return { + new = function(_, handler) + handler.starttag = starttag + handler.endtag = endtag + return XmlParser.new(handler, { + stripWS = true, -- Indicates if whitespaces should be striped or not + expandEntities = false, + errorHandler = errorHandler + }) + end +} \ No newline at end of file diff --git a/jls/util/XmlParser-lxp.lua b/jls/util/XmlParser-lxp.lua new file mode 100644 index 0000000..dd28e98 --- /dev/null +++ b/jls/util/XmlParser-lxp.lua @@ -0,0 +1,30 @@ +local lxpLib = require('lxp') + +local function startElement(p, name, attrs) + local handler = p:getcallbacks().handler + handler:startElement(name, attrs) +end + +local function endElement(p, name) + local handler = p:getcallbacks().handler + handler:endElement(name) +end + +local function cdata(p, text) + local handler = p:getcallbacks().handler + handler:cdata(text) +end + +return { + new = function(_, handler) + -- see https://lunarmodules.github.io/luaexpat/manual.html + -- lxp.new(callbacks [, separator[, merge_character_data]]) + return lxpLib.new({ + StartElement = startElement, + EndElement = endElement, + CharacterData = cdata, + _nonstrict = true, + handler = handler + }) + end +} \ No newline at end of file diff --git a/jls/util/xml.lua b/jls/util/xml.lua index 412cad1..a83a7e3 100644 --- a/jls/util/xml.lua +++ b/jls/util/xml.lua @@ -6,7 +6,7 @@ -- @module jls.util.xml -- @pragma nostrip -local XmlParser = require('XmlParser') -- xml2lua parser +local XmlParser = require('jls.lang.loader').requireOne('jls.util.XmlParser-lxp', 'jls.util.XmlParser-XmlParser') local class = require('jls.lang.class') local StringBuffer = require('jls.lang.StringBuffer') --local List = require('jls.util.List') @@ -106,25 +106,29 @@ local Handler = class.create(function(handler) table.insert(current, child) end - function handler:starttag(tag) + function handler:startElement(name, attrs) local node = { - name = tag.name + name = name } - if tag.attrs then + if attrs then local attr = {} - for k, v in pairs(tag.attrs) do - attr[k] = unescape(v) + for k, v in pairs(attrs) do + if type(k) == 'string' then + attr[k] = unescape(v) + end + end + if next(attrs) then + node.attr = attr end - node.attr = attr end self:addChild(node) table.insert(self._stack, node) end - function handler:endtag(tag) + function handler:endElement(name) local current = self._stack[#self._stack] - if current.name ~= tag.name then - error('Expecting end tag '..'"'..current.name..'" but found "'..tag.name..'"') + if current.name ~= name then + error('Expecting end tag '..'"'..current.name..'" but found "'..name..'"') end table.remove(self._stack) end @@ -201,14 +205,7 @@ end -- -- Returns {name = 'a', {name = 'b', attr = {c = 'c'}, 'A value'}} function xml.decode(xmlString) local handler = Handler:new() - local options = { - stripWS = true, -- Indicates if whitespaces should be striped or not - expandEntities = false, - errorHandler = function(errMsg, pos) - error(string.format("%s [char=%d]\n", errMsg or "Parse Error", pos)) - end - } - local parser = XmlParser.new(handler, options) + local parser = XmlParser:new(handler) parser:parse(xmlString) return handler.root[1] end