Lxp Tree

lua-users home
wiki

lxptree: construct XML trees

The following implementation constructs an XmlTree from a string or file. This code is part of LazyKit. The implementation depends on LuaExpat?, an expat binding.

Functions API

lxptree.parsestring(s)

Return an XML tree parsed from the string s.

lxptree.parsefile(file)

Returns a tree fully parsed from file. If file is a string, it is interpreted as a filename and opened; otherwise, file is treated as an io library file object.

Note that file is read and parsed as one big chunk, so running this on a 2G file may be a bad idea. On the other hand, building a tree of a 2G file would be a worse idea.

Source Code

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


RecentChanges · preferences
edit · history
Last edited January 5, 2007 5:40 am GMT (diff)