我正在解析几百万个格式如下的xml文件:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE test-document PUBLIC "-//TEST//TEST DOC//EN" "https://somerandomurl.com/test.dtd">
<test-document>...</test-document>
每次我解析一个文件时,都会下载相同的https://somerandomurl.com/test.dtd
文件,这会占用大量带宽,而且似乎没有必要。有没有办法存储文件并使我的代码重定向我的本地副本?我无法编辑xml文件,因此它必须在我的代码中。给定以下Java代码,实现这种事情的合理方法是什么?
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setIgnoringComments(true);
factory.setIgnoringElementContentWhitespace(true);
factory.setValidating(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource("file.xml"));//My final document object.
答案 0 :(得分:1)
如果您只想缓存下载的DTD文件,则可以使用XML目录。特别是,您将在解析规则中指定目录文件,例如以下
<catalog
Xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<system
systemId="https://somerandomurl.com/test.dtd"
uri="file://mydir/test.dtd"/>
</catalog>
将具有系统标识符https://somerandomurl.com/test.dtd
的实体解析为文件/mydir/test.dtd
,该文件应包含通过https:URL链接的DTD文件的下载的本地副本。
答案 1 :(得分:1)
首先将DTD读入字符串变量。
然后做
builder.setEntityResolver(
(sysId, PubId) -> new InputSource(new StringReader(dtd)));
或者,如果您想更加小心,请在返回dtd
的内容之前,让EntityResolver检查systemId和/或publicId是否符合预期。
请注意,这仍然涉及每次都解析DTD,只是节省了从网络获取DTD的成本。
也很重要:实例化XML解析器的开销很大(实例化DocumentBuilderFactory甚至更大)。确保重用工厂和解析器。