Как получить значение пользовательского атрибута из XML-сообщения XMPP?

Хорошо, ребята, простой вопрос, но очень важный для меня.

Итак, другой клиент Android отправляет это xml msg:

<message
  id='6ymdM-19'
  to='[email protected]/smack'
  type='chat'>
  <subject>normal</subject>
  <received xmlns='urn:xmpp:receipts' id='HVgQw-5'/>
</message>

и мой слушатель примерно такой:

private class MsgListener implements ChatStateListener {
/**
 * Constructor.
 */
public MsgListener() {
}

@Override
public void processMessage(Chat chat, org.jivesoftware.smack.packet.Message message) {
    String xmlMessage = message.toXML();
    Log.v(TAG, "XML Chat: "+xmlMessage);
    // getExtension namespace try urn:xmpp:receipts
    if(xmlMessage.contains("<request xmlns=")) {
        Log.d(TAG, "new chat message arrive! reply with RECEIVED!");
        replyReceived(message);
    } else if(xmlMessage.contains("<received xmlns=")) {
        Log.d(TAG, "RECEIVED notification arrived!");
        PacketExtension statusExtension = 
                message.getExtension("urn:xmpp:receipts");
        Log.d(TAG, "Extension name: "+statusExtension.getElementName());
        Log.d(TAG, "Extension XML: "+statusExtension.toXML());
        Log.d(TAG, "Extension string: "+statusExtension.toString());
    }

     ....
     ....
     ....
} 

в этом случае я хочу получить значение атрибута «id» внутри тега «полученного» элемента. но то, что я получил в своем журнале, выглядит так:

RECEIVED notification arrived!
D/ChatAdapter(320): Extension name: received
D/ChatAdapter(320): Extension XML: <received xmlns="urn:xmpp:receipts"></received>
D/ChatAdapter(320): Extension string:              
org.jivesoftware.smack.packet.DefaultPacketExtension@44f10430

Итак, как я могу получить «HVgQw-5» ??

ОБНОВЛЕНИЕ

На самом деле есть что-то странное... Я получил XML-согласие от моей отладки SMACK следующим образом:

 <
 D/SMACK(320): 05:40:28 PM RCV  (1156991856): message id="6ymdM-19"  
 to="[email protected]/Smack" from="[email protected]/Smack"  
 type="chat"><subject>
 D/SMACK(320): 05:40:28 PM RCV  (1156991856): normal</subject><thread>cr0900</thread>
 **<received xmlns="urn:xmpp:receipts" id="HVgQw-5"/>**<active      
 xmlns="http://jabber.org/protoc
 D/SMACK(320): 05:40:28 PM RCV  (1156991856): ol/chatstates"/></message>

Но когда я выполняю message.toXML, он просто распечатывается так:

XML Chat: <message id="6ymdM-19" to="[email protected]/Smack" from="[email protected]/Smack" type="chat"><subject>normal</subject><thread>cr0900</thread>**<received xmlns="urn:xmpp:receipts">**</received><active xmlns="http://jabber.org/protocol/chatstates" /></message>

Почему это происходит? почему я пропускаю "id"?


person user724861    schedule 23.03.2012    source источник


Ответы (3)


Что касается идентификатора, сначала получите дескриптор расширения, а затем найдите идентификатор, поэтому

DeliveryReceipt deliveryReceiptObj =(DeliveryReceipt) message.getExtension(DeliveryReceipt.NAMESPACE);
// ID below is what you want
deliveryReceiptObj.getId();

Связанное обсуждение: asmack - получение пользовательских XML-сообщений

  1. определите свой EmbeddedPacketExtension (так что вы получите дескриптор этого вместо DefaultPacketExtension, предоставленного SMACK)

  2. Поставщик, который расширяет EmbeddedExtensionProvider

  3. registerProvider вы только что создали с помощью Namespace

код следует:

/**
* User: suvrat 
* Represents a <b>message delivery receipt</b> entry as specified by
* <a href="http://xmpp.org/extensions/xep-0184.html">Message Delivery Receipts</a>.
*
*/

import org.jivesoftware.smack.packet.PacketExtension;

public class DeliveryReceipt implements PacketExtension
{

    public static final String NAMESPACE = "urn:xmpp:receipts";

    private String id; /// original ID of the delivered message

    public DeliveryReceipt(String id)
    {
        this.id = id;
    }

    public String getId()
    {
        return id;
    }

    public String getElementName()
    {
        return "received";
    }

    public String getNamespace()
    {
        return NAMESPACE;
    }

    public String toXML()
    {
        return "<received xmlns='" + NAMESPACE + "' id='" + id + "'/>";
    }
}

 /**
 * User: suvrat
 * The DeliveryReceiptProvider parses DeliveryReceipt packets.
 */

 */
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
import org.xmlpull.v1.XmlPullParser;

import java.util.List;
import java.util.Map;

public class DeliveryReceiptProvider extends EmbeddedExtensionProvider
{

    @Override
    protected PacketExtension createReturnExtension(String currentElement, String currentNamespace,
    Map<String, String> attributeMap, List<? extends PacketExtension> content)
    {
        return new DeliveryReceipt(attributeMap.get("id"));
    }

}

   //3.) finally where ever you would like to parse packet
 ProviderManager.getInstance().addExtensionProvider("received", DeliveryReceipt.NAMESPACE, new DeliveryReceiptProvider());
person heymant kumar    schedule 08.05.2012
comment
плюс один за первую часть ответа. - person Vilas; 15.12.2015

Вы не можете достичь этого без изменения исходного кода. И правильный подход в XMPP — создавать расширения для стандартных пакетов, а не изменять их. Вы можете обратиться к Не удается прочитать Пользовательские атрибуты из тега сообщения при использовании библиотеки asmack XMPP для Android?,, которая содержит подробную информацию.

person Kevin Chen    schedule 27.06.2018

Существует еще один способ получить значение атрибута, который определяет метод UserInfo4XMPP путем реализации ExtensionElement:

import org.jivesoftware.smack.packet.ExtensionElement;
public class UserInfo4XMPP implements ExtensionElement{
    public static final String NAMESPACE = "urn:xmpp:receipts";
    private String elementName = "received ";
    private String id = "";    
    @Override
    public String getElementName() {
        return elementName;
    }
        @Override
    public CharSequence toXML() {  
        return "<received xmlns='" + NAMESPACE + "' id='" + id + "'/>";
    }
    @Override
    public String getNamespace() {
        return NAMESPACE;
    }
    public String getId()
    {
        return id;
    }
}

Тело функции похоже на DeliveryReceiptProvider.

person Z. Mei    schedule 29.06.2018