使用XMPP和`smack从`vcard'获取自定义元素



我创建了一个具有自定义元素的vcard

<vCard xmlns='vcard-temp'><NICKNAME>nickname</NICKNAME><elementName xmlns='xmlns:custom'><avatar>elementName_avatar_3.png</avatar></elementName></vCard>

但是,当我问这个vcard时,我的结果是:

<iq xmlns='jabber:client' to='602157@peropenfire101.per.local/3r6td85ng7' from='271087@peropenfire101.per.local' id='jA5pI-33' type='result'><vCard xmlns='vcard-temp'><JABBERID>271087@peropenfire101.per.local/4usgw7j7u</JABBERID><NICKNAME>nickname</NICKNAME></vCard></iq>

如您所见,自定义元素丢失了。这是我的要求:

try {
        connection.sendStanzaWithResponseCallback(
                new cdcd(from),
                new StanzaFilter() {
                    @Override
                    public boolean accept(Stanza stanza) {
                        return false;
                    }
                },
                new StanzaListener() {
                    @Override
                    public void processStanza(Stanza packet) throws SmackException.NotConnectedException, InterruptedException, SmackException.NotLoggedInException {
                    }
                });
    } catch (Exception e) {
        e.printStackTrace();
    }
private class cdcd extends Stanza{
    private final Jid from;
    public cdcd(Jid from) {
        this.from = from;
    }
    @Override
    public String toString() {
        return null;
    }
    @Override
    public CharSequence toXML(String enclosingNamespace) {
        return "<iq from='"+ from +"' id='v1' type='get'><vCard xmlns='vcard-temp'/></iq>";
    }
}

我不知道如何解决此问题。

根据XEP-054不支持VCARD DTD的非标准元素的功能,因此您的XMPP服务器忽略了它们。

不幸的是,道森的提议没有在IETF的标准过程中前进。由于现在流失了时间的原因,Jabber项目继续使用Draft-Dawson-Vcard-XML-DTD-01的DTD,进行了两个小修改以适应贾布伯(Jabber)社区(添加Jabberid和Descc)元素),但还指定所有帽子中的元素名称,而不是在Draft-Dawson-Vcard-vcard-XML-DTD-01中定义的小写。此外,Jabber社区在该草案中遵循有关版本信息的使用(但不是DTD),包括作为VCARD元素的属性,而不是作为子元素的属性。这种格式是在Jabber社区中以" VCARD-TEMP"名称空间实施的。

您可以在这里看到所有受支持的元素。另请参阅此处的讨论

已解决...我创建了一个扩展VCardProvider的新类,然后在"覆盖方法"分析中解析了我的自定义标签

public class CustomVCardProvider extends VCardProvider {
private static final String[] TEL = new String[]{
        "VOICE",
        "FAX",
        "PAGER",
        "MSG",
        "CELL",
        "VIDEO",
        "BBS",
        "MODEM",
        "ISDN",
        "PCS",
        "PREF",
};
private static final String[] ADR = new String[]{
        "POSTAL",
        "PARCEL",
        "DOM",
        "INTL",
        "PREF",
        "POBOX",
        "EXTADR",
        "STREET",
        "LOCALITY",
        "REGION",
        "PCODE",
        "CTRY",
        "FF",
};
@Override
public VCard parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException {
    VCard vCard = new VCard();
    String name = null;
    outerloop:
    while (true) {
        int eventType = parser.next();
        switch (eventType) {
            case XmlPullParser.START_TAG:
                name = parser.getName();
                switch (name) {
                    case CUSTOM_TAG:
                        parseCustomTag(parser, vCard);
                        break;
                    case "N":
                        parseName(parser, vCard);
                        break;
                    case "ORG":
                        parseOrg(parser, vCard);
                        break;
                    case "TEL":
                        parseTel(parser, vCard);
                        break;
                    case "ADR":
                        parseAddress(parser, vCard);
                        break;
                    case "EMAIL":
                        parseEmail(parser, vCard);
                        break;
                    case "NICKNAME":
                        vCard.setNickName(parser.nextText());
                        break;
                    case "JABBERID":
                        vCard.setJabberId(parser.nextText());
                        break;
                    case "PHOTO":
                        parsePhoto(parser, vCard);
                        break;
                    default:
                        break;
                }
                break;
            case XmlPullParser.TEXT:
                if (initialDepth + 1 == parser.getDepth()) {
                    vCard.setField(name, parser.getText());
                }
                break;
            case XmlPullParser.END_TAG:
                if (parser.getDepth() == initialDepth) {
                    break outerloop;
                }
                break;
            default:
                break;
        }
    }
    return vCard;
}

不要忘记从原始提供商中复制所有解析器,并在身份验证后添加ProviderManager.addIQProvider("vCard", "vcard-temp", new CustomVCardProvider());

最新更新