lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi all,

So I found where the problem was : both functions list_children() and decode() were wrong.

Working versions are the following :

----
-- Iterates over the children of an object.
-- It will ignore any text, so if you want all of the elements, use ipairs(obj).
-- @param obj Table (LOM format) representing the XML object.
-- @param tag String with the matching tag of the children
--    or nil to match only structured children (single strings are skipped).
-- @return Function to iterate over the children of the object
--    which returns each matching child.

local function list_children (obj, tag)
    local i = 0
    return function ()
        i = i+1
        local v = obj[i]
        while v do
            if type(v) == "table" and (not tag or v.tag == tag) then
                return v
            end
            i = i+1
            v = obj[i]
        end
        return nil
    end
end

---------------------------------------------------------------------
-- Converts a SOAP message into Lua objects.
-- @param doc String with SOAP document.
-- @return String with namespace, String with method's name and
--    Table with SOAP elements (LuaExpat's format).
---------------------------------------------------------------------
local function decode (doc)
    local obj = assert (parse (doc))
    local ns = obj.tag:match ("^(.-):")
    assert (obj.tag == ns..":Envelope", "Not a SOAP Envelope: "..
        tostring(obj.tag))
    local namespace = find_xmlns (obj.attr)
    local lc = list_children (obj)
    local o = lc ()
    -- Skip SOAP:Header
    while o and (o.tag == ns..":Header" or o.tag == "SOAP-ENV:Header") do
        o = lc ()
    end
    if o.tag == ns..":Body" or o.tag == "SOAP-ENV:Body" then
        lc = list_children (o)
        obj = lc ()
    else
        error ("Couldn't find SOAP Body!")
    end
    local method = obj.tag:match ("%:([^:]*)$") or obj.tag

    local entries = {}
    for i = 1, #obj do
        for j = 1, #obj[i] do    -- remove noisy CR fake entries
            if obj[i][j] == "\n" then
                table.remove(obj[i],j)
                j = j-1
            end
        end
        entries[i] = obj[i]
    end
    return namespace, method, entries
end
----

I found a problem as well with luaexpat (1.2.0-1). It treats Carriage returns as string and not as space and consequently creating some noisy entries in the resulting array.
As example

---
<SOAP-ENV:Body>[CR]
<ser-root:CheckEntryPointsResponse xmlns:ser-root="http://eux932.sgp.st.com/STAdminMisc/StopB2BProcessing/CheckEntryPointsWS"><ErrorMessages>[CR]
<ArrayOfstringItem>Port FilePollingListener:/home/wmadm/usr/laurent/tst is disabled</ArrayOfstringItem>[CR]
<ArrayOfstringItem>Task STAdmin.purge:purgeISData is suspended</ArrayOfstringItem>[CR]
---

create something like :

---
{
  "
"
  {
    {
      "
"
      {
        "Port FilePollingListener:/home/wmadm/usr/laurent/tst is disabled"
        {
        }
        tag = "ArrayOfstringItem"
      }
      "
"
      {
        "Task STAdmin.purge:purgeISData is suspended"
        {
        }
        tag = "ArrayOfstringItem"
      }
      "
"
      {
        "SAPListener STSAPResource.B2BCRM.listener:B2BCRM is NOT enabled"
        {
        }
        tag = "ArrayOfstringItem"
      }
      {
      }
      tag = "ErrorMessages"
    }
    {
      "xmlns:ser-root"
      xmlns:ser-root = "http://eux932.sgp.st.com/STAdminMisc/StopB2BProcessing/CheckEntryPointsWS"
    }
    tag = "ser-root:CheckEntryPointsResponse"
  }
  {
  }
  tag = "SOAP-ENV:Body"
}
---

(notice the "[CR]" rows for each [CR] in the source.
I put some code to remove them in decode() but it looks for me a bug in luaexpat or in libexpat itself.

Bye

Laurent

PS: And after my own investigation, I saw that someone else provided a bug fix as well for the same issue ... Anyway, my code is still valid due to expat problem ...