[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: lua & E4X ?
- From: Javier Guerra <javier@...>
- Date: Wed, 7 Mar 2007 16:14:03 -0500
On Wednesday 07 March 2007, Wilfred wrote:
> Hi Greg,
>
> I would be interested in discussing a common API for Lua.
i've done several tests, trying to find a 'comfortable' way of handling XML in
Lua.
parsing is (almost) OK with SAX-type APIs, but directly modifying XML is
challenging.
i realized that a big part of the problem is the syntax. since XML is a
horrendous mismatch of features, it's very hard to map it to a simple
structure. one naïve attempt would be to map all to a tree, but then text
content and attributes would be 'special' nodes, and in the end you get a
monstruosity like DOM.
after a quick glance, E4X looks like DOM without the functions. that is, XML
is handled as a tree of objects, with all the quirks of non-tags tree nodes.
so, if it's so hard to come up with a syntax that can express every XML
(mis)feature, why not use XML itself?
so far, my preferred solution is to turn it backwards: using XML as a template
that calls Lua for output. at this time, the lua callbacks have access to
several other pieces of already-parsed XML, and make it easy to modify
locally or globally.
the template doesn't have any Lua code, and the Lua code doesn't have any XML
content. the only common things are: functions names in the template, and
you can use attributes, tagnames and tag IDs in Lua.
for example, a template might include this:
----------------- xml --------------
<tbody function="sched_body">
<tr>
<td function="row_var" varname="task" />
<td function="row_var" varname="priority" />
</tr>
</tbody>
---------------- xml end ------------
and the Lua code:
----------------- lua ----------------
require "xlp"
local page = xlp.new_page (in_f, out_f)
function page.cb.sched_body (node)
page:out_tagstart (node, false)
for i = 1,10 do
page:out_content (node, i)
end
page:out_tagend (node)
end
function page.cb.row_var (node, row)
local varname = node.attr.varname
return xlp.new_node (node, string.format ("%s(%s)", varname, row))
end
page:out()
-------------------- lua end --------------------
the call to xlp.new_page () parses and optimizes the XML. after that, you can
populate the callback table (in page.cb) with functions. the call to
page:out() processes the XML, calling your Lua functions.
the output looks like:
<tbody function="sched_body">
<tr>
<td function="row_var" varname="feature">feature(1)</td>
<td function="row_var" varname="task">task(1)</td>
</tr>
<tr>
<td function="row_var" varname="feature">feature(2)</td>
<td function="row_var" varname="task">task(2)</td>
</tr>
<tr>
<td function="row_var" varname="feature">feature(3)</td>
<td function="row_var" varname="task">task(3)</td>
</tr>
</tbody>
there are a few more features, like being able to reference any XML subtree
that had an ID, and a very simple function to turn a XML template into a
Xavante page handler.
if anybody is interested, i might try to document it
--
Javier
Attachment:
pgpj7zlhj7zmM.pgp
Description: PGP signature