我维护一个 Java 程序来帮助 Mozilla 本地化。除其他格式外,Mozilla 本地化使用 DTD 文件(在运行时,所选语言环境的 DTD 被注入到定义 UI 的 XML 文件中,从而产生本地化界面)。
DTD 有时会以 PE 引用的形式包含其他文件,如下所示:
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
%brandDTD;
但是,出于我的程序目的,当我使用这样的 PE 引用解析 DTD 文件的 en-US 版本时,我只需要将这些行复制到目标本地化文件中。
我继承了这个程序,它使用 SAX(JDK 中捆绑的 Xerces)做了一些聪明的(对我来说)解析 DTD 的技巧:
public class DTDReadHelper extends DefaultHandler2 {
private static final String dummyXml="<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<!DOCTYPE dialog SYSTEM \"MozillaTranslator\">" +
"<dialog></dialog>";
(...)
@Override
public InputSource resolveEntity(java.lang.String name, java.lang.String publicId,
java.lang.String baseURI, java.lang.String systemId) {
if ((name != null) && (name.startsWith("%"))) {
return new InputSource(new StringReader(""));
} else {
return new InputSource(is);
}
}
问题是在典型的解析过程中会两次到达 else 分支,因此如果文件小于 8192 字节,则会导致来自 Xerces 的 IOException,否则会导致 SAXParseException。
我可以处理 IOException,因为当它发生时整个文件已经被解析,但我无法使用 SAXParseException 来处理它,因为它发生在解析的最开始(lineNumber 1,columnNumber 2)。
“有问题的”DTD 文件可以在这里找到:
并且程序的整个源代码都在这里:
https://kenai.com/projects/moztrans/sources
我的“SCCE”包含四个文件(上述存储库中的简化版本),如果需要,我可以将它们上传到某个地方。
在所有这些细节之后,问题是:有什么方法可以让 SAX 避免尝试解析 PE 引用?
TIA