Module LuaXML

A module that maps between Lua and XML without much ado.

LuaXML provides a set of functions for processing XML data in Lua. It offers a very simple and natural mapping between the XML format and Lua tables, which allows one to work with and construct XML data just using Lua’s normal table access and iteration methods (e.g. ipairs()).

Substatements and tag content are represented as array data having numerical keys (1 .. n), attributes use string keys, and tags the numerical index 0. This representation makes sure that the structure of XML data is preserved exactly across read/write cycles (i.e. xml.eval(var:str()) should equal var again).



To use LuaXML, first import the module - for example like this:
local xml = require("LuaXML")

LuaXML consists of a Lua file (LuaXML.lua) and a corresponding C module (LuaXML_lib) – normally a shared library (.dll/.so), although a static linking is possible as well. Both parts are imported by this call, provided that they are found in Lua’s package search path.

 

Functions

append (var, tag) appends a new subordinate LuaXML object to an existing one.
children (var, tag, key, value, maxdepth) iterate subelements (“XML children”) as key – value pairs.
decode (str) converts a string from XML encoding.
encode (str) converts a string to XML encoding.
eval (xml, mode) parses an XML string into a Lua table.
find (var, tag, key, value) recursively searches a Lua table for a subelement matching the provided tag and attribute.
iterate (var, cb, tag, key, value, r, max, d) iterates a LuaXML object, invoking a callback function for all matching (sub)elements.
load (filename, mode) loads XML data from a file and returns it as table.
match (var, tag, key, value) match XML entity against given (optional) criteria.
new (arg, tag) creates a LuaXML “object”, and optionally sets its tag.
registerCode (decoded, encoded) registers a custom code for the conversion between non-standard characters and XML character entities.
save (var, filename, filemode, cmt, hdr) saves a Lua var as XML file.
str (value, indent, tag) converts any Lua value to an XML string.
tag (var, tag) sets or returns tag of a LuaXML object.

Fields

WS_NORMALIZE remove “lead in” whitespace before tags
WS_PRESERVE preserve all whitespace, even between tags
WS_TRIM strip all leading / trailing whitespace


Functions

append (var, tag)
appends a new subordinate LuaXML object to an existing one. optionally sets tag

Parameters:

  • var the parent LuaXML object
  • tag optional string the tag of the appended LuaXML object

Returns:

    appended LuaXML object, or nil in case of errors
children (var, tag, key, value, maxdepth)
iterate subelements (“XML children”) as key – value pairs. This function is meant to be called in a generic for loop, similar to what ipairs(var) would do. However you can easily specify additional criteria to match against here, possibly reducing the overhead needed to test for specific subelements.

For the resulting (k, v) pairs, note that k is just a sequential number in the array of matched child elements, and has no direct relation to the actual “position” (subtag index) within each v’s parent object.

Parameters:

  • var the table (LuaXML object) to work on
  • tag optional string XML tag to be matched
  • key optional string attribute key to be matched
  • value (optional) attribute value to be matched
  • maxdepth optional number maximum depth allowed, defaults to 1 (only immediate children). You can pass 0 or true to iterate all children recursively.

Returns:

    Lua iterator function and initial state (Lua-internal use) – suitable for a for loop

See also:

Usage:

    local xml = require("LuaXML")
    local foobar = xml.eval('<foo><a /><b bar="no" /><c bar="yes" /><a /></foo>')
    
    -- iterate over those children that have a "bar" attribute:
    for k, v in foobar:children(nil, "bar") do
    	print(k, v:tag(), v.bar)
    end
    -- will print
    -- 1       b       no
    -- 2       c       yes
    
    -- require "bar" to be "yes":
    for k, v in foobar:children(nil, "bar", "yes") do
    	print(k, v:tag(), v.bar)
    end
    -- will print
    -- 1       c       yes
    
    -- iterate "a" tags: (the first and fourth child will match)
    for k, v in foobar:children("a") do
    	print(k, v:tag(), v.bar)
    end
    -- will print
    -- 1       a       nil
    -- 2       a       nil
    
decode (str)
converts a string from XML encoding. This function transforms str by replacing any special XML encodings with their “plain text” counterparts.

Parameters:

  • str string string to be transformed

Returns:

    string the decoded string

See also:

Usage:

    print((xml.decode("&lt;-&gt;")) -- "<->"
    
encode (str)
converts a string to XML encoding. This function transforms str by replacing any special characters with suitable XML encodings.

Parameters:

  • str string string to be transformed

Returns:

    string the XML-encoded string

See also:

Usage:

    print(xml.encode("<->")) -- "&lt;-&gt;"
    
eval (xml, mode)
parses an XML string into a Lua table. The table will contain a representation of the XML tag, attributes (and their values), and element content / subelements (either as strings or nested LuaXML “objects”).

Note: Parsing “wide” strings or Unicode (UCS-2, UCS-4, UTF-16) currently is not supported. If needed, convert such xml data to UTF-8 before passing it to eval(). UTF-8 should be safe to use, and this function will also recognize and ignore a UTF-8 BOM (byte order mark) at the start of xml.

Parameters:

  • xml string or userdata the XML to be converted. When passing a userdata type xml value, it must point to a C-style (NUL-terminated) string.
  • mode optional number whitespace handling mode, one of the WS_* constants – see Fields. defaults to WS_TRIM (compatible to previous LuaXML versions)

Returns:

    a LuaXML object containing the XML data, or nil in case of errors
find (var, tag, key, value)
recursively searches a Lua table for a subelement matching the provided tag and attribute. See the description of match for the logic involved with testing for tag, key and value.

Parameters:

  • var the table to be searched in
  • tag optional string the XML tag to be found
  • key optional string the attribute key (= exact name) to be found
  • value (optional) the attribute value to be found

Returns:

    the first (sub-)table that satisfies the search condition, or nil for no match
iterate (var, cb, tag, key, value, r, max, d)
iterates a LuaXML object, invoking a callback function for all matching (sub)elements.

The iteration starts with the variable var itself (= default depth 0). A callback function cb gets invoked for each match , depending on the specified criteria. If the r flag is set, the process will repeat recursively for the subelements of var (at depth + 1). You can limit the scope by setting a maximum depth, or have the callback function explicitly request to stop the iteration (by returning false).

Parameters:

  • var the table (LuaXML object) to iterate
  • cb function callback function. callback(var, depth) will be called for each matching element.
    The function may return false to request a stop; if its result is any other value (including nil), the iteration will continue.
  • tag optional string XML tag to be matched
  • key optional string attribute key to be matched
  • value (optional) attribute value to be matched
  • r optional boolean recursive operation. If true, also iterate over the subelements of var
  • max optional number maximum depth allowed
  • d optional number initial depth value, defaults to 0

Returns:

    The function returns two values: a counter representing the number of elements that were successfully matched (and processed), and a boolean completion flag. The latter is true for an exhaustive iteration, and false if was stopped from the callback.

See also:

load (filename, mode)
loads XML data from a file and returns it as table. Basically, this is just calling eval on the given file’s content.

Parameters:

  • filename string the name and path of the file to be loaded
  • mode optional number whitespace handling mode, defaults to WS_TRIM

Returns:

    a Lua table representing the XML data, or nil in case of errors
match (var, tag, key, value)
match XML entity against given (optional) criteria. Passing nil for one of the tag, key, or value parameters means “don’t care” (i.e. match anything for that particular aspect). So for example

var:match(nil, "text", nil)
-- or shorter, but identical:  var:match(nil, "text")

will look for an XML attribute (name) “text” to be present in var, but won’t consider its value or the tag of var.

Note: If you want to test for a specific attribute value, so also have to supply a key – otherwise value will be ignored.

Parameters:

  • var the variable to test, normally a Lua table or LuaXML object. (If var is not a table type, the test always fails.)
  • tag optional string If set, has to match the XML tag (i.e. must be equal to the tag(var, nil) result)
  • key optional string If set, a corresponding attribute key needs to be present (exact name match).
  • value (optional) arbitrary Lua value. If set, the attribute value for key has to match it.

Returns:

    either nil for no match; or the var argument properly converted to a LuaXML object, equivalent to xml.new(var).

    This allows you to either make direct use of the matched LuaXML object, or to use the return value in a boolean test (if xml.match(…)), which is a common Lua idiom.

Usage:

    -- each of these will either return x, or nil in case of no match
    
    x:match("foo") -- test for x:tag() == "foo"
    x:match(nil, "bar") -- test if x has a "bar" attribute
    x:match(nil, "foo", "bar") -- test if x has a "foo" attribute that equals "bar"
    x:match("foobar", "foo", "bar") -- test for "foobar" tag, and attr "foo" == "bar"
    
new (arg, tag)
creates a LuaXML “object”, and optionally sets its tag. The function either sets the metatable of an existing Lua table, or creates a new (empty) “object”. If you pass an optional tag string, it will be assigned to the result.

(It’s also possible to call this as new(tag), which creates a new XML object with the given tag and is equivalent to new({}, tag).)

Note that it’s not mandatory to use this function in order to treat a Lua table as LuaXML object. Setting the metatable just allows the usage of a more object-oriented syntax (e.g. xmlvar:str() instead of xml.str(xmlvar)). XML objects created by load or eval automatically offer the object-oriented syntax.

Parameters:

  • arg (optional) (1) a table to be converted to a LuaXML object, or (2) the tag of the new LuaXML object
  • tag optional string a tag value that will be assigned to the object

Returns:

    LuaXML object, either newly created or the conversion of arg; optionally tagged as requested
registerCode (decoded, encoded)
registers a custom code for the conversion between non-standard characters and XML character entities.

By default, only the most basic entities are known to LuaXML:

" < > '

On top (and independent) of that, the ampersand sign always gets encoded / decoded separately: &&amp;. Character codes above 127 are directly converted to an appropriate XML encoding, representing the character number (e.g. &#160;). If other special encodings are needed, they can be registered using this function.

Note: LuaXML now manages these encodings in a (private) standard Lua table. This allows you to replace entries by calling registerCode() again, using the same decoded and a different encoded. Encodings may even be removed later, by explictly registering a nil value: registerCode(decoded, nil).

Parameters:

  • decoded string the character (sequence) to be used within Lua
  • encoded string the character entity to be used in XML

See also:

save (var, filename, filemode, cmt, hdr)
saves a Lua var as XML file. Basically this simply exports the string representation xml.str(var) (or var:str()), plus a standard header.

Parameters:

  • var the variable to be saved, normally a table
  • filename string the filename to be used. An existing file of the same name gets overwritten.
  • filemode optional string the file mode to pass to io.open , defaults to “w”
  • cmt optional string

    custom comment to be written at the top of the file (after the header). You may pass an empty string if you don’t want any comment at all, otherwise it should preferably end with at least one newline. Defaults to:

    <!-- file «filename», generated by LuaXML -->\n\n
    
  • hdr optional string

    custom header, written before anything else. You may pass an empty string if you don’t want any header at all, otherwise it should preferably end with a newline. Defaults to the standard XML 1.0 declaration:

    <?xml version="1.0"?>\n
    

Usage:

    var:save("simple.xml")
    var:save("no-comment.xml", nil, "")
    var:save("custom.xml", "a+", "<!-- append mode, no header -->\n", "")
str (value, indent, tag)
converts any Lua value to an XML string.

Parameters:

  • value the value to be converted, normally a table (LuaXML object). However this function will ‘encapsulate’ other Lua values (of arbitrary type) in a way that should make them valid XML.
    Note: Passing no value will cause the function to return nil.
  • indent optional number indentation level for ‘pretty’ output. Mainly for internal use, defaults to 0.
  • tag optional string the tag to be used in case value doesn’t already have an ‘implicit’ tag. Mainly for internal use.

Returns:

    string an XML string, or nil in case of errors.
tag (var, tag)
sets or returns tag of a LuaXML object. This method is just “syntactic sugar” (using a typical Lua term) that allows the writing of clearer code. LuaXML stores the tag value of an XML statement at table index 0, hence it can be simply accessed or altered by var[0]. However, writing var:tag() for access or var:tag(“newTag”) for altering may be more self explanatory (and future-proof in case LuaXML’s tag handling should ever change).

Parameters:

  • var the variable whose tag should be accessed, a LuaXML object
  • tag optional string the new tag to be set

Returns:

    If you have passed a new tag, the function will return var (with its tag changed); otherwise the result will be the current tag of var (normally a string).

Fields

WS_NORMALIZE
remove “lead in” whitespace before tags
  • WS_NORMALIZE
WS_PRESERVE
preserve all whitespace, even between tags
  • WS_PRESERVE
WS_TRIM
strip all leading / trailing whitespace
  • WS_TRIM
generated by LDoc 1.4.2