好的,我有一个由其他人编写的 Android 应用程序,但维护和进一步开发是我的工作。该应用程序使用一个以 XML 格式回答的 API。代码非常标准:
InputStream in = httpConnection.getInputStream();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse(in);
一切正常,直到标签名称中出现非拉丁字符。 例如,这是可以的:
<Milen>some_text</Milen>
但这引发了一个异常(exception):
<Милен>some_text</Милен>
异常(exception)是INVALID_CHARACTER_ERR .经过一些调查,我发现 DOM API 的实现是org.apache.harmony.xml.dom.DocumentImpl .并引发异常 here在第 286 行。if 检查归结为这个方法:
private static boolean isXMLIdentifierPart(char c) {
return isXMLIdentifierStart(c) || (c >= '0' && c <= '9') || (c == '-') || (c == '.');
}
这基本上排除了任何非拉丁字符。然而,根据this任何 Unicode 字符都是有效的标签名称。
所以我的问题是:
- 为什么会有这样的违规检查?
- 要让 DOM 解析器处理非拉丁 Unicode 字符,我有哪些选择?
一些补充说明:
- 服务器返回正确的UTF-8响应
- 我试过使用 XML escaping但显然这在检查
isXMLIdentifierPart
之前被转换回原始的 Unicode
- 我非常喜欢坚持使用 DOM 解析器 API,因为之后的处理假定一个 Document。对象传递给它。重写处理过程需要大量工作。
我想到的两个解决方案是:
- 获取 org.apache.harmony.xml.dom.DocumentImpl 实现的代码并创建缺少问题检查的自定义解析器。
- 让服务器使用一些使用纯拉丁字符(\u1234 或 U+1234 不起作用)的自定义模式对非拉丁字符进行编码,然后在解析器完成工作后将其解码回来。
然而,这两种解决方案都是非标准的,并且不喜欢它们。因此,非常欢迎任何正确的方法!!!
免责声明:我是 Android 平台的新手,有可能我遗漏了一些简单/明显的东西。然而,经过两天的研究和实验,我还没有找到它。
最佳答案
according to this any Unicode character is a valid tag name.
不完全是 any 字符,但是是的,在第五版中,绝大多数非 ASCII 字符都是允许的(在此之前规则相当复杂,但仍然有很多是允许的)。
Why is there such a check that runs against the standard?
因为 Harmony DOM 实现是一个错误的、不符合规范的、维护不善的堆,无法正确地实现旧规范,所以只是全面禁止非 ASCII。其中还有许多其他问题。
这是 issue 78387 FWIW。
What are my options for getting the DOM parser to work with non-latin Unicode characters?
看看您是否可以找到一个替代的、更少损坏的 DOM 实现。
Taking the code of the org.apache.harmony.xml.dom.DocumentImpl implementation and creating a custom parser that lacks the problematic check.
(是的,这可能必须是一个合适的分支,因为单独使用子类化很难做到。太多的类相互之间有明确的引用。)
关于android - 如何使用 Android 上的 DocumentBuilder DOM 解析器解析带有包含非拉丁 Unicode 字符的标签名称的 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33444138/