以下是关于文档功能的问题。
文档功能是否始终为每次转换读取输入文件?还是第一次将它加载到内存中,然后从内存中读取以进行连续转换?
这里提出这个问题的原因是,我有一个非常好的输入文件,它总是在转换期间检查值。
如何在这些情况下获得最佳性能?
答案 0 :(得分:2)
specification of the document
function in XSLT 2.0将从单个URL解析XML的详细信息委托给the specification of the XSLT/XPath/XQuery doc
function。它没有指定解析的文档是否被缓存,但它需要函数稳定,说“默认情况下,此函数是稳定的。。对此函数的两次调用返回相同的文档节点,如果两个调用都提供了相同的URI引用(在解析为绝对URI引用之后)。因此,下面的表达式(如果它不引发错误)将始终为true:doc(“foo.xml”)是doc(“foo” .XML “)”。
实现可能会缓存结果以实现如果您想要多次访问同一文档但是如果您加载多个大型文档并且无法处置其中任何一个文档而成为优势的结果。
您使用哪种XSLT 2.0处理器? Saxon有http://www.saxonica.com/documentation/index.html#!functions/saxon/discard-document明确丢弃缓存的文档,这表明通常会缓存对document('foo.xml')
或doc('foo.xml')
的调用。
答案 1 :(得分:2)
使用doc()或document()读取的文档几乎不可避免地在转换期间被缓存,因为这是满足规范中稳定性要求的唯一方法。但我认为你的问题是关于跨多个转换的缓存。这将取决于处理器。
这几天使用Saxon 6.5的理由很少。即使您想出于可移植性的原因限制自己使用XSLT 1.0,通常最好使用更新的Saxon版本。
Saxon(至少目前的版本,我不记得6.5)将在JAXP Transformer的生命周期内缓存文档,因此如果您使用相同的Transformer进行多次转换,则不会重新解析该文档。要获得更精确的控制,请考虑使用s9api API。这允许您使用DocumentBuilder在内存中构建文档树,然后将其作为样式表参数的值传递给每个转换,或者通过注册识别的URIResolver来响应对doc()或document()的调用URI。当然,对于任何JAXP转换引擎,您都可以在URIResolver中实现自己的文档缓存。
答案 2 :(得分:1)
当您使用document()
函数时,库无法使用
知道你是否会再次使用它,或者这是否是一个
瞬态访问。
无论何时使用文档,都必须如此
解析等,这是相对耗时的。为了避免
多次重读和重新解析文档的开销,
图书馆维护一个“文件清单”作为其中的一部分
“转型背景”。任何文件的解析图像
access被添加到此列表和列表(连同
它引用的文档)仅在转换时释放
上下文被释放。