用erlang解析ejabberd包

用erlang解析ejabberd包,erlang,ejabberd,erl,ejabberd-module,ejabberd-hooks,Erlang,Ejabberd,Erl,Ejabberd Module,Ejabberd Hooks,我正在使用ejabberd18.09进行IM应用。该应用程序几乎没有为ejabberd(xmpp)消息添加扩展所需的功能 我在offline_message_钩子上创建了一个自定义模块来捕获脱机消息并将它们发送到我自己的url进行进一步处理 发送到ejabberd的消息具有不同的情况,具体取决于消息的类型,如下所示 如果我正在发送照片,消息如下所示 <message xmlns="jabber:client" xml:lang="en" to="someuserjid2" from="{s

我正在使用ejabberd18.09进行IM应用。该应用程序几乎没有为ejabberd(xmpp)消息添加扩展所需的功能

我在offline_message_钩子上创建了一个自定义模块来捕获脱机消息并将它们发送到我自己的url进行进一步处理

发送到ejabberd的消息具有不同的情况,具体取决于消息的类型,如下所示

如果我正在发送照片,消息如下所示

<message xmlns="jabber:client" xml:lang="en" to="someuserjid2" from="{someuserjid}" type="chat" id="mP8tO-8">
   <mtype xmlns="urn:xmpp:mtype" value="media" />
   <url xmlns="urn:xmpp:url" id="myId" mediaType="photo" link="myphotourl.com" />
   <body>thumbnail string</body>
</message>
<message xmlns="jabber:client" xml:lang="en" to="someuserjid2" from="{someuserjid}" type="chat" id="mP8tO-8">
   <mtype xmlns="urn:xmpp:mtype" value="location" />
   <location xmlns="urn:xmpp:geo" lat="1.2" lng="2.2 " />
   <body>location thumbnailstring</body>
</message>

我想要的是(在erlang中)如何读取mtype标记的value属性以及create a switch语句(媒体、位置、测试)值,以便我可以单独处理每条消息?

您可以将参数列表中的
attr
传递到
fxml:get\u path\u s
以选择某个元素的属性值:

case fxml:get_path_s(Packet, [{elem, <<"mtype">>}, {attr, <<"value">>}]) of
    <<"media">> ->
        %% handle media...
    <<"location">> ->
        %% handle location...
    <<"">> ->
        %% no mtype element, or missing value attribute!
        %% let's handle that case as well
end
然后像这样称呼它:

case find_one_of(Packet, [<<"location">>, <<"url">>]) of
    {<<"location">>, Location} ->
        %% Do something with Location...
    {<<"url">>, Url} ->
        %% Do something with Url...
    not_found ->
        %% Neither location nor url
end
案例查找(数据包,[,])中的一个
{,位置}->
%%对位置做点什么。。。
{,Url}->
%%用Url做点什么。。。
未找到->
%%既不是位置也不是url
结束

您可以将参数列表中的
attr
传递给
fxml:get\u path\u s
,以选择某个元素的属性值:

case fxml:get_path_s(Packet, [{elem, <<"mtype">>}, {attr, <<"value">>}]) of
    <<"media">> ->
        %% handle media...
    <<"location">> ->
        %% handle location...
    <<"">> ->
        %% no mtype element, or missing value attribute!
        %% let's handle that case as well
end
然后像这样称呼它:

case find_one_of(Packet, [<<"location">>, <<"url">>]) of
    {<<"location">>, Location} ->
        %% Do something with Location...
    {<<"url">>, Url} ->
        %% Do something with Url...
    not_found ->
        %% Neither location nor url
end
案例查找(数据包,[,])中的一个
{,位置}->
%%对位置做点什么。。。
{,Url}->
%%用Url做点什么。。。
未找到->
%%既不是位置也不是url
结束

谢谢@legoscia。我是erlang的新手,我添加mtype就是为了检查我收到的元素的类型,我同意你的看法,检查元素的存在会更好。在我的例子中,你能建议一下我们的方法吗?使用fxml:get_path_s(Packet,[{elem,},{attr,}])将成功编译,但当我运行它时,它崩溃了:Hook offline\u message\u Hook在运行mod_offline时崩溃了\u http_post:create_message/1:{error,function_子句,[{fxml,get_subtag,[{file,“src/fxml.erl”},{line,175}]为了防止有人遇到这个问题,我可以通过使用:fxml:get_path_s(xmpp:encode(Packet),[{elem,list_to_binary(“mtype”)},{attr,list_to_binary(“value”)}来解决这个问题,谢谢@legocia。我是erlang的新手,我添加了mtype来检查我接收的元素的类型,我同意你的观点,检查元素的存在性会更好。你能建议我们在我的情况下如何做吗?使用fxml:get_path_s(Packet,[{elem,},{attr,}])将成功编译,但当我运行它时,它崩溃:Hook offline\u message\u Hook在运行mod\u offline\u http\u post:create\u message/1:{error,function\u子句,[{fxml,get\u subtag,[{file,“src/fxml.erl”},{line,175}]万一有人遇到这个问题,我可以使用:fxml:get\u path\s(xmpp:encode Packet)[{elem,list_to_binary(“mtype”)},{attr,list_to_binary(“value”)}),
find_one_of(Packet, []) ->
    not_found;
find_one_of(Packet, [ElementName | Rest]) ->
    case fxml:get_subtag(Packet, ElementName) of
        false ->
            find_one_of(Packet, Rest);
        Element ->
            {ElementName, Element}
    end.
case find_one_of(Packet, [<<"location">>, <<"url">>]) of
    {<<"location">>, Location} ->
        %% Do something with Location...
    {<<"url">>, Url} ->
        %% Do something with Url...
    not_found ->
        %% Neither location nor url
end