问题重现
昨天一早到公司,测试就给我说了一个Bug,关于一个消息通知显示的问题,正常的消息应该显示为:
恭喜XXX在XXX房间抽中XXX
一直也是正常显示的。那天突然就出现了一个异常显示:
恭喜
问题原因
通知后面的消息全都没有了。然而我自己在测试的N次中一直都没有复现,直到一个偶然的机会,突然看到我的应用中飘过一条消息:“恭喜 ”,大惊,赶快看日志,发现这是一个名为“&¥#@,。,。”一堆乱七八糟的符号问昵称的用户发的消息,我赶快找测试问这是谁发的,让再来几发。中间又经过一堆排除,最终发现异常是由于“&”符号引起的。
通知在显示时是通过拼接的一个HTML的<span>标签,然后进行解析显示的,XXX都有自己的样式,如颜色这些。我开始就怀疑是HTML标签中出现“ & ”符号,引起的异常,在查了一些资料和又把前人的代码查看了一番后,发现这个HTML文本,最终是以XML格式进行解析,然后拆分为不同字符串进行展示的,最终定位到了问题,由于XmlPullParser在解析时不能出现&符号,因为&符号是节点字符,所以不能直接使用,需要进行处理。
解决方法
在定位到问题后,就好办了。在此记录一下解决方式,以备后用。
< < 小于号
> > 大于号
& & 和号
' ' 单引号
" " 双引号
注释:严格的说,在XML中只有字符“&”和字符“<”是非法的。注意最后的" ; "不能少。
"<" 会产生错误,因为解析器会把该字符解释为新元素的开始。
"&" 也会产生错误,因为解析器会把该字符解释为字符实体的开始。
非法的 XML 字符必须被替换为实体引用(entity reference)。
假如在 XML 文档中放置了一个类似 "<" 或 "&" 字符,那么这个会产生一个错误:
XmlPullParserException: unterminated entity ref
<message>if salary < 1000 & then</message>
为了避免此类错误,需要把字符 "<" 替换为实体引用,就像这样:
<message>if salary < 1000 & then</message>
在解析中当有一大片的内容不需要解析时,可以考虑CDATA。术语 CDATA 指的是不应由 XML 解析器进行解析的文本数据(Unparsed Character Data)。
CDATA 部分由 "<![CDATA[" 开始,由 "]]>" 结束。具体可以去查找一下资料。