1

I have this packet :

{xmlelement,"presence", [{"xml:lang","en"}, {"ver","6.00.00"}, {"to", "test@conference.localhost/user"}],
                        [{xmlelement,"c", [{"xmlns", "http://jabber.org/protocol/caps"}, {"node", "http://www.google.com/xmpp/client/caps/"}, {"ver", "eVvrsq8jya/4AZMjFl5BeDKSmg4="}, {"hash","sha-1"}], []},
                        {xmlelement,"nick", [{"xmlns", "http://jabber.org/protocol/nick"}], [{xmlcdata,<<"user">>}]},
                        {xmlelement,"x", [{"xmlns", "http://jabber.org/protocol/muc"}], [{xmlelement,"history", [{"maxstanzas","20"}, {"maxchars","32768"}], []}]}]}

And I want to extract data from : ("maxchars" && "node")

What I'm doing is using functions located in xml.erl but i don't know how to do it .

Example for what I tried :

xml:get_subtag(Packet, "maxchars")
Mr. zero
  • 245
  • 4
  • 18

2 Answers2

5

With a recent version of ejabberd (= that is less than 3 years old), you can do as follow.

I assume packet is binary xmlel record:

P = {xmlel,<<"presence">>, [{<<"xml:lang">>,<<"en">>}, {<<"ver">>,<<"6.00.00">>}, {<<"to">>, <<"test@conference.localhost/user">>}],
     [{xmlel,<<"c">>, [{<<"xmlns">>, <<"http://jabber.org/protocol/caps">>}, {<<"node">>, <<"http://www.google.com/xmpp/client/caps/">>}, {<<"ver">>, <<"eVvrsq8jya/4AZMjFl5BeDKSmg4=">>}, {<<"hash">>,<<"sha-1">>}], []},
      {xmlel,<<"nick">>, [{<<"xmlns">>, <<"http://jabber.org/protocol/nick">>}], [{xmlcdata,<<"user">>}]},
      {xmlel,<<"x">>, [{<<"xmlns">>, <<"http://jabber.org/protocol/muc">>}], [{xmlel,<<"history">>, [{<<"maxstanzas">>,<<"20">>}, {<<"maxchars">>,<<"32768">>}], []}]}]}.

You can then do:

X = fxml:get_subtag_with_xmlns(P, <<"x">>, <<"http://jabber.org/protocol/muc">>).                                                                                        
H = fxml:get_subtag(X, <<"history">>).
{value, MS} = fxml:get_tag_attr(<<"maxstanzas">>, H).
{value, MC} = fxml:get_tag_attr(<<"maxchars">>, H).  

MS and MC contains your values:

MS = <<"20">>
MC = <<"32768">>
Mickaël Rémond
  • 9,035
  • 1
  • 24
  • 44
  • I'm using ejabberd 2.1.13 . Can I do it with the functions in xml.erl ? cuz there isn't function named : get_subtag_with_xmlns in old version – Mr. zero Mar 30 '16 at 07:29
  • I'm trying to add (get_subtag_with_xmlns) function to xml.erl what I'm doing here : http://paste.ubuntu.com/15558018/ is it true ? – Mr. zero Mar 30 '16 at 08:03
  • just use get_subtag then and ignore namespace. Note: You should really not use a version release in june 2013. You are missing a lot of security fixes. – Mickaël Rémond Mar 30 '16 at 09:46
  • I'm using this version before 2 years and I added to it some helpful function in muc-room ... etc and I found it much GOOD i think all of ejabberd version are good :D . so I can't leave to a newer version. – Mr. zero Mar 30 '16 at 16:00
  • Sorry but I'm newer in erlang. Also i think ejabberd going to make me learn this language little by little. – Mr. zero Mar 30 '16 at 16:05
1

I tested this, it's pretty basic but it's working fine, although I'm pretty sure is quite inefficient and/or there might be better ways for doing this (wait for the cavalry to arrive):

1> X = {xmlelement,"presence", [{"xml:lang","en"}, {"ver","6.00.00"}, {"to", "test@conference.localhost/user"}], [{xmlelement,"c", [{"xmlns", "http://jabber.org/protocol/caps"}, {"node", "http://www.google.com/xmpp/client/caps/"}, {"ver", "eVvrsq8jya/4AZMjFl5BeDKSmg4="}, {"hash","sha-1"}], []}, {xmlelement,"nick", [{"xmlns", "http://jabber.org/protocol/nick"}], [{xmlcdata,<<"user">>}]}, {xmlelement,"x", [{"xmlns", "http://jabber.org/protocol/muc"}], [{xmlelement,"history", [{"maxstanzas","20"}, {"maxchars","32768"}], []}]}]}.
{xmlelement,"presence",
            [{"xml:lang","en"},
             {"ver","6.00.00"},
             {"to","test@conference.localhost/user"}],
            [{xmlelement,"c",
                         [{"xmlns","http://jabber.org/protocol/caps"},
                          {"node","http://www.google.com/xmpp/client/caps/"},
                          {"ver","eVvrsq8jya/4AZMjFl5BeDKSmg4="},
                          {"hash","sha-1"}],
                         []},
             {xmlelement,"nick",
                         [{"xmlns","http://jabber.org/protocol/nick"}],
                         [{xmlcdata,<<"user">>}]},
             {xmlelement,"x",
                         [{"xmlns","http://jabber.org/protocol/muc"}],
                         [{xmlelement,"history",
                                      [{"maxstanzas","20"},
                                       {"maxchars","32768"}],
                                      []}]}]}
2> {xmlelement,_,[{_,_},{_,_},{_,_}],[{xmlelement,_,[{_,_},{"node",Node},{_,_},{_,_}],[]},{xmlelement,_,[{_,_}],[{xmlcdata,_}]},{xmlelement,_,[{_,_}],[{xmlelement,_,[{_,_},{"maxchars",MaxChars}],[]}]}]} = X.
{xmlelement,"presence",
            [{"xml:lang","en"},
             {"ver","6.00.00"},
             {"to","test@conference.localhost/user"}],
            [{xmlelement,"c",
                         [{"xmlns","http://jabber.org/protocol/caps"},
                          {"node","http://www.google.com/xmpp/client/caps/"},
                          {"ver","eVvrsq8jya/4AZMjFl5BeDKSmg4="},
                          {"hash","sha-1"}],
                         []},
             {xmlelement,"nick",
                         [{"xmlns","http://jabber.org/protocol/nick"}],
                         [{xmlcdata,<<"user">>}]},
             {xmlelement,"x",
                         [{"xmlns","http://jabber.org/protocol/muc"}],
                         [{xmlelement,"history",
                                      [{"maxstanzas","20"},
                                       {"maxchars","32768"}],
                                      []}]}]}
3> Node.
"http://www.google.com/xmpp/client/caps/"
4> MaxChars.
"32768"
5>

On line 2> we pattern match the values that you are expecting in that "format". Place the bindings in the locations you want to get the values from and, if possible, establish some constraints like, for instance, the atoms that won't change in the XML packet. I hope you get the idea.

x80486
  • 6,627
  • 5
  • 52
  • 111
  • yes. I get it thank you but I think there is a function in xml.erl built to catch data like this. I think it's better than this. – Mr. zero Mar 30 '16 at 01:44