【发布时间】:2014-09-04 07:38:30
【问题描述】:
由于我已经花了将近一整天的时间来调试这个,我希望对以下问题有一些有价值的见解:
我在输入文档上运行 XSL 转换,我的样式表加载了一个外部 XML 文档,其中包含我需要进行一些比较的查找值。 我正在加载这样的外部文档:
<xsl:variable name="dictionary"
select="document('myDict.xml', document(''))/path/to/LookupElement" />
LookupElement 是一个包含我需要访问的完整 XML 片段的元素。
在整个样式表中,各种比较表达式都在访问$dictionary。
现在,发生的情况是,使用 Xalan(2.7.?,最新版本,从 Apache 网站下载,而不是 JRE 中包含的版本)使用此 document() 函数调用进行转换大约需要 12 (!) 分钟。
没有document() 调用(并且没有我的比较访问$dictionary 中的数据)的相同样式表在几秒钟内完成。
使用 Saxon-B 9.1.0.8 的相同样式表也可以在几秒钟内完成。
信息:外部文档有 25MB(!),我不可能减小它的大小。 我在 JRE 6 下使用 ant 的 xslt-Task 运行转换。
我不确定这是否与上述问题有关:在我的样式表中,我有一些表达式可以测试外部 XML 文档中是否存在某些属性。无论属性是否存在,这些表达式总是计算为true:
<xsl:variable name="myAttExists" select="boolean($dictionary/path/to/@myAttribute)"/>
我已经走投无路了。我知道 Xalan 正确读取了文档,所有引用都转到 $dictionary,所以我没有多次调用 document()。
任何人任何想法?
编辑:
我已从外部 XML 文档中删除了对 XML 架构的引用,以防止 Xalan 或底层 (Xerces) 解析器的架构查找。
编辑:
我已验证myAttExists 将始终为true,即使指定的属性名称肯定不存在于整个外部 XML 文档中。
我什至把上面的表达式改成了:
<xsl:variable name="myAttExists" select="count($dictionary/path/to/@unknownAttribute) != 0"/>
仍然产生true。
编辑:
出于测试目的,我已删除对 document() 函数的调用以及对 $dictionary 的所有引用。这将使用 Xalan 的转换运行时间减少到 16 秒。
编辑:
有趣的细节:Oxygen 12.1 附带的 Xalan 版本可在几秒钟内完成加载外部 XML 文档。但是,它也会错误地评估属性的存在...
编辑:
我有以下变量声明,总是产生true:
<xsl:variable name="expectedDefaultValueExists">
<xsl:choose>
<xsl:when test="@index">
<xsl:value-of select="boolean($dictionary/epl:Object[@index = $index]/@defaultValue)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="boolean($dictionary/epl:Object[@index = $index]/epl:SubObject[@subIndex = $subIndex]/@defaultValue)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
这在 XSLT/XPath 1.0 中是否可行? $index 和 $subIndex 是根据上下文节点的 @index 和 @subIndex 属性计算得出的。我想从具有相等索引和/或子索引的外部 XML 文档加载 defaultValue 属性。
是否可以在 XPath 1.0 的谓词中使用变量?这适用于 XPath 2.0。
关于不正确的变量分配,我不再相信解析器(Xalan)问题,因为 PHP 的 XSLTProcessor 也是如此。肯定是变量声明的问题...
【问题讨论】:
-
好吧,如果您知道 Saxon 工作正常且性能良好,那么您为什么还要为 Xalan 和 XSLT 1.0 烦恼,因为您使用的不是 JRE 中的 Xalan 版本,您无论如何都使用第三方库并且可以直接转到 Saxon 9。当然,术语 LookupElement 表明定义和使用键可能会提高性能,您需要向我们展示 XML 和
myDict.xml结构的更多细节以及它在 XSLT 中的使用。 -
@MartinHonnen 我需要维护我的样式表的 XSLT 1.0 和 2.0 版本,因为它们用于不同的环境。否则我早就放弃了 1.0 版本。我将变量直接指向包含我需要的所有数据的元素。由于这是一个直接的 XPath,我看不出有什么性能问题?
-
我的第一个猜测是它正在从 W3C 网站加载 DTD(例如 XHTML DTD)。 W3C 人为地限制此类请求以阻止它们。但是,由于您使用的 Saxon 是一个相当旧的版本(9.1),同样的问题也会影响 Saxon,所以也许不是这样。
-
@MichaelKay 事实上,我之前找到了有关该问题的信息。外部 XML-Document 中没有引用 DTD,出于这个原因,我也删除了对其 XML-Schema 的引用。无济于事:(
-
很难在没有看到您的输入和样式表的情况下回答。问题:如果您重组输入以使您通过 document() 读取的内容是主要的 XML 输入,那么运行需要多长时间?