From ejabberd xml to xmerl and back – XEP-009

Those last days I was busing implementing an ejabberd module responding to Jabber-RPC (a.k.a XEP-009).

I used the xmlrpc module shipped with erlang to do the parsing. But that was tricky. xmlrpc uses xmerl for parsing and representing XML but ejabberd does not. It a simpler xml module handling the parsing.

To make a long story short, to get ejabberd’s xml understood by xmlrpc, here’s the thing :

% ....
            xml:element_to_string(xml:get_subtag(SubEl, "methodCall")))),
% ....

SubEl being the sub_el field of an iq packet.

The complex part is that you need to call xmerl_ucs:to_utf8/1 else the module will crash.

For returning the resulting XML to the client, you need to call xml_stream:parse_element (ejabberd’s internal XML parser) to get the XML structure right for handling by ejabberd.

case xmlrpc_encode:payload(handle(State,Decoded)) of % handle is the xmlrpc method
 {ok, EncodedPayload} ->
    Res = IQ#iq{type = result,
        sub_el = [{xmlelement, "query", [{"xmlns", ?NS_RPC}],
        [ xml_stream:parse_element(EncodedPayload) ]

That’s not very optimal of course, as data is converted at nearly every step :

XML -> ejabberd -> XML -> xmerl -> XML -> ejabberd -> XML.

But developper time is more expensive than machine time, right ?

So now I can call methods on the server directly from Groovy using Groovy Jabber-RPC (using XMPPPool, of course).

If there is any interest, I’ll release the code, but for the time being it is very crude. I’ll like to “componentize” a bit more, and hook up ACLs for specific RPC handlers.


2 comments so far

  1. Evandro on

    Très bon, merci. “Evandro (Evandro)”: “. (Artigos Linux)”: “Net (PageRank)”: “! (Poker Regras)”:

  2. Evandro on

    Très bon, merci.

Comments are closed.

%d bloggers like this: