我正在尝试使用SAX解析器解析此XML文档:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE WIN_TPBOUND_MESSAGES SYSTEM "tpbound_messages_v1.dtd">
<WIN_TPBOUND_MESSAGES>
<SMSTOTP>
<SOURCE_ADDR>+447522579247</SOURCE_ADDR>
<TEXT>TEST: @£$¥èéùìò?ØøÅå& ^{}\\[~]¡€ÆæßÉ!\"#¤%'()*+,-./0123456789:;<=>? ÄÖÑܧ¿äöñüà end</TEXT>
<WINTRANSACTIONID>652193268</WINTRANSACTIONID>
</SMSTOTP>
</WIN_TPBOUND_MESSAGES>
解析<TEXT>
元素后,内容将转换为:
TEST: @£$¥èéùìò?Ã�øÃ�Ã¥& ^{}\\[~]¡€Ã�æÃ�Ã�!\"#¤%'()*+,-./0123456789:;<=>? Ã�Ã�Ã�Ã�§¿äöñüà end
很明显,非ASCII字符发生了不好的事情。解析XML的代码如下所示:
public void parse(InputStream xmlStream) throws WinGatewayException {
XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
parser.setContentHandler(this);
parser.setErrorHandler(error);
parser.setEntityResolver(new DTDResolver());
parser.setDTDHandler(this);
parser.setFeature("http://xml.org/sax/features/validation", true);
parser.setFeature("http://apache.org/xml/features/validation/schema", true);
parser.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", true);
parser.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error", false);
parser.parse(new InputSource(xmlStream));
}
并且this
引用的对象具有以下方法:
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (localName.equals("TEXT")) {
logger.debug("Parsed message text: " + cData.toString());
message.setText(cData.toString());
}
}
为什么XML解析器不保留这些非ASCII字符?
答案 0 :(得分:3)
我相信你的XML文件实际上是UTF-8而不是ISO-8859-1。
ISO-8859-1编码的文件每个字符只有一个字节,因此英镑符号将是单个字节0xA3。但是,看起来您的文件有0xC2 0xA3,这是您在UTF-8中为U + 00A3获得的字节序列。
更改XML声明以反映这一点:
<?xml version="1.0" encoding="UTF-8"?>
并查看是否可以解决问题。假设确实如此,那么你需要弄清楚这些不良数据的起源。