Reputation: 129
Ejabberd server receives packet like this:
{xmlel,<<"message">>,[{<<"from">>,<<"user1@localhost/resource">>},{<<"to">>,<<"user2@localhost">>},{<<"xml:lang">>,<<"en">>},{<<"id">>,<<"947yW-9">>}],[{xmlcdata,<<">">>},{xmlel,<<"body">>,[],[{xmlcdata,<<"Helllo wassup!">>}]}]}
I want to fetch data from this packet.
Needed data : Type, If the body has a certain parameter, say {<<"xml:lang">>,<<"en">>}
I am doing the following operations:
{_XMLEL, TYPE, DETAILS , _BODY} = Packet
This provides me the type : <<"message">>
or <<"iq">>
or <<"presence">>
.
To check if DETAILS has {<<"xml:lang">>,<<"en">>}
I do this:
Has_Attribute=lists:member({<<"xml:lang">>,<<"en">>},DETAILS)
Is there any better way to do this?
I also need the to
and from
attributes from the packet.
Upvotes: 1
Views: 380
Reputation: 20004
Use a combination of pattern matching in the function head together with a fold over the details to extract everything you need.
The function below returns a list of key-value tuples, where the <<"type">>
tuple is artificially created so the list is homogenous:
extract({xmlel, Type, Details, _}) ->
[{<<"type">>,Type} |
lists:foldl(fun(Key, Acc) ->
case lists:keyfind(Key, 1, Details) of
false -> Acc;
Pair -> [Pair|Acc]
end
end, [], [<<"from">>,<<"to">>,<<"xml:lang">>])];
extract(_) -> [].
The first clause matches the {xmlel, ...}
tuple, extracting Type
and Details
. The return value consists of a list with head {<<"type">>,Type}
followed by a tail formed from folding over the list of keys to be extracted from Details
. The second clause matches anything not a {xmlel, ...}
tuple and just returns the empty list.
Putting this function into a module named z
and passing it your data:
1> z:extract({xzlel,<<"message">>,[{<<"from">>,<<"user1@localhost/resource">>},{<<"to">>,<<"user2@localhost">>},{<<"xml:lang">>,<<"en">>},{<<"id">>,<<"947yW-9">>}],[{xmlcdata,<<">">>},{xmlel,<<"body">>,[],[{xmlcdata,<<"Helllo wassup!">>}]}]}).
[{<<"type">>,<<"message">>},
{<<"xml:lang">>,<<"en">>},
{<<"to">>,<<"user2@localhost">>},
{<<"from">>,<<"user1@localhost/resource">>}]
Upvotes: 2