当前位置:  开发笔记 > 编程语言 > 正文

XML支持新的UTF-8,如表情符号

如何解决《XML支持新的UTF-8,如表情符号》经验,为你挑选了1个好方法。

我们有一个使用XML与服务器通信的移动客户端.当我们需要发送一些最近的UTF-8表情时,我遇到了一个问题,这些表情很容易在新手机上使用.例如: .

现在,我的Android应用程序没有编码和发送它的问题,但在服务器端,事情往往有点爆炸性.

如果我们尝试使用上面的任何一个表情发送消息,我们会得到一个巨大的堆栈跟踪,相关部分:

javax.xml.transform.TransformerException: org.xml.sax.SAXException: Invalid UTF-16 surrogate detected: d83d d83d ?
java.io.IOException: Invalid UTF-16 surrogate detected: d83d d83d ?
        at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(Unknown Source)
        at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(Unknown Source)

如果我们试图解析它:

2017-01-13 14:00:22,717 - com.zylinc.core.gatekeeper.stripes.DoBean - WARN - Could not handle request
org.xml.sax.SAXParseException; lineNumber: 3; columnNumber: 93; Character reference "&#
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
        at com.zylinc.core.gatekeeper.stripes.DoBean.parseRequest(DoBean.java:127)
        at com.zylinc.core.gatekeeper.stripes.DoBean.execute(DoBean.java:56)
        at com.zylinc.core.gatekeeper.Dispatcher.onRequest(Dispatcher.java:107)
        at com.zylinc.core.gatekeeper.io.UntrustedSocketListener.handleRequest(UntrustedSocketListener.java:16)
        at com.zylinc.core.gatekeeper.io.SocketListener$MessageHandler.run(SocketListener.java:228)
        at java.lang.Thread.run(Unknown Source)

在这种情况下,XML是:






现在,这似乎在输出JSON时工作正常,但是移动客户端以使用JSON并不是我们可以在一夜之间完成的事情.我猜它会破坏,因为与java版本相比,使用的字符太新了,但确保较新的表情不会破坏消息传递会很好.

解析XML的代码非常简单:

SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
XMLReader xmlReader = parser.getXMLReader();
xmlReader.setContentHandler(handler);
StringReader reader = new StringReader(xml);
xmlReader.parse(new InputSource(reader));

编辑:

创建XML是这样完成的:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
mDoc = builder.newDocument();
mRoot = mDoc.createElement("action");
mDoc.appendChild(mRoot);

TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer trans = transFactory.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
trans.setOutputProperty(OutputKeys.INDENT, "yes");
trans.setOutputProperty(OutputKeys.VERSION, "1.1");

StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
DOMSource source = new DOMSource(mDoc);
trans.transform(source, result);

return sw.toString();

添加文本的地方很简单:

xml.setAttribute(SUBJECT, obj.getSubject());

我是否必须指定一些编码或其他?



1> Michael Kay..:

你错误地编码了这些.

如果您使用的是XML字符引用表示法,&#NNNNN;那么N必须是Unicode代码点,而不是分割为代理项对的Unicode代码点.例如,😎.在你的例子中,你得到的��是不合法的,因为55357和56846不是代码点,它们是代理对的两半.

如果您直接表示字符,我不确定您正在做什么,但错误消息"检测到无效的UTF-16代理:d83d d83d"会非常清楚您做错了.

您的问题标题("UTF-8喜欢表情符号")表明您在Unicode和UTF-8之间感到困惑.Unicode将表情符号映射到整数代码点,例如,第一个是十六进制1f60e或十进制128526. UTF-8是将Unicode编码为字节或八位字节流的一种可能方式,它可以将每个Unicode代码点编码为一到四的序列字节.

UTF-16是另一种编码,它将大多数Unicode代码点表示为16位,但是xffff上面的那些使用一对16位值称为代理对.代替对不用于UTF-8.尝试将UTF-16中的Unicode代码点编码为代理对,然后以UTF-8独立编码该代理对的每一半是错误的.但我怀疑这是你在做什么.

推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有