在 java 中解析 xml 时如何缓存 dtd 文件
How to cache a dtd file when parsing xml in java
我正在解析几百万个 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.
如果您只想缓存下载的 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 链接到的 DTD 文件的下载本地副本:URL。
链接
首先将 DTD 读入字符串变量。
然后做
builder.setEntityResolver(
(sysId, PubId) -> new InputSource(new StringReader(dtd)));
或者,如果您想更加小心,请让您的 EntityResolver 在返回 dtd
.
的内容之前检查 systemId and/or publicId 是否符合预期
请注意,这仍将涉及每次解析 DTD,它只是节省了从网络中获取它的成本。
也很重要: 实例化 XML 解析器的成本很高(实例化 DocumentBuilderFactory 的成本更大)。确保重用工厂和解析器。
我正在解析几百万个 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.
如果您只想缓存下载的 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 链接到的 DTD 文件的下载本地副本:URL。
链接
首先将 DTD 读入字符串变量。
然后做
builder.setEntityResolver(
(sysId, PubId) -> new InputSource(new StringReader(dtd)));
或者,如果您想更加小心,请让您的 EntityResolver 在返回 dtd
.
请注意,这仍将涉及每次解析 DTD,它只是节省了从网络中获取它的成本。
也很重要: 实例化 XML 解析器的成本很高(实例化 DocumentBuilderFactory 的成本更大)。确保重用工厂和解析器。