LuaExpat: XML Expat parsing for the Lua programming language

LuaExpat
XML Expat parsing for the Lua programming language

## Examples

The code excerpt below creates a parser with 2 callbacks and feeds a test string to it. The parsing of the test string triggers the callbacks, printing the results.

    require"lxp"

    local count = 0
    callbacks = {
        StartElement = function (parser, name)
            io.write("+ ", string.rep(" ", count), name, "\n")
            count = count + 1
        end,
        EndElement = function (parser, name)
            count = count - 1
            io.write("- ", string.rep(" ", count), name, "\n")
        end
    }

    p = lxp.new(callbacks)

    for l in io.lines() do  -- iterate lines
        p:parse(l)          -- parses the line
        p:parse("\n")       -- parses the end of line
    end
    p:parse()               -- finishes the document
    p:close()               -- closes the parser

For a test string like

    <elem1>
        text
        <elem2/>
        more text
    </elem1>

The example would print

    + elem1
        + elem2
        - elem2
    - elem1

Note that the text parts are not handled since the corresponding callback (CharacterData) has not been defined. Also note that defining this callback after the call to lxp.new would make no difference. But had the callback table been defined as

    callbacks = {
        StartElement = function (parser, name)
            io.write("+ ", string.rep(" ", count), name, "\n")
            count = count + 1
        end,
        EndElement = function (parser, name)
            count = count - 1
            io.write("- ", string.rep(" ", count), name, "\n")
        end,
        CharacterData = function (parser, string)
            io.write("* ", string.rep(" ", count), string, "\n")
        end
    }

The results would have been

    + elem1
    * text
        + elem2
        - elem2
    * more text
    - elem1

Another example would be the use of false as a placeholder for the callback. Suppose that we would like to print only the text associated with elem2 elements and that the XML sample is

     <elem1>
        text
        <elem2>
            inside text
        </elem2>
        more text
    </elem1>

We could define the new callback table as

    callbacks = {
        StartElement = function (parser, name)
          if name == "elem2" then
            -- redefines CharacterData behaviour
            callbacks.CharacterData = function (parser, string)
              io.write(string, "\n")
            end
          end
        end,

        EndElement = function (parser, name)
          if name == "elem2" then
            callbacks.CharacterData = false -- restores placeholder
          end
        end,

        CharacterData = false               -- placeholder
    }

The results would have been

    inside text

Note that this example assumes no other elements are present inside elem2 tags.