我需要一个信息来优化我的xslt。
在我的模板中,我多次访问子项,例如:
<xsl:template match="user">
<h1><xsl:value-of select="address/country"/></h1>
<p><xsl:value-of select="address/country"/></p>
<p><xsl:value-of select="address/country"/></p>
... more and more...
<p><xsl:value-of select="address/country"/></p>
</xsl:template>
最好将子元素的内容存储在变量中并直接调用该变量,以避免每次都解析树:
<xsl:template match="user">
<xsl:variable name="country" select="address/country"/>
<h1><xsl:value-of select="$country"/></h1>
<p><xsl:value-of select="$country"/></p>
<p><xsl:value-of select="$country"/></p>
... more and more...
<p><xsl:value-of select="$country"/></p>
</xsl:template>
或者使用变量会比多次解析树消耗更多的资源吗?
最佳答案
通常,XML文件作为一个整体被解析,并作为XDM保存在内存中。所以,我想
比多次解析树
实际上,您指的是多次访问xml输入的内部表示。下图说明了这一点,我们讨论的是源树:
(摘自michael kay的xslt 2.0和xpath2.0程序员参考,第43页)
同样,xsl:variable
会创建一个节点(或者更准确地说,一个临时文档),该节点保存在内存中,也需要访问。
现在,你说的优化到底是什么意思?您是指执行转换所需的时间还是CPU和内存使用量(正如您在问题中提到的“资源”?
另外,性能当然取决于xslt处理器的实现。唯一可靠的发现方法就是实际测试。
写两个只在这方面不同的样式表,也就是说,其他方面是相同的。然后,让它们转换相同的输入xml并测量它们所花费的时间。
我的猜测是,在编写代码时,访问变量比重复完整路径更快,重复变量名也更方便(有时称为“便利变量”)。
编辑:替换为更合适的内容,作为对您评论的回应。
如果您真的要测试它,请编写两个样式表:
带变量的样式表
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/root">
<xsl:copy>
<xsl:variable name="var" select="node/subnode"/>
<subnode nr="1">
<xsl:value-of select="$var"/>
</subnode>
<subnode nr="2">
<xsl:value-of select="$var"/>
</subnode>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
不带变量的样式表
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/root">
<xsl:copy>
<subnode nr="1">
<xsl:value-of select="node/subnode"/>
</subnode>
<subnode nr="2">
<xsl:value-of select="node/subnode"/>
</subnode>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
应用于以下输入XML:
<root>
<node>
<subnode>helloworld</subnode>
</node>
</root>
编辑:根据@michael kay的建议,我测量了100次运行的平均时间(“-t和-repeat:100在saxon命令行上”):
with variable: 9 ms
without variable: 9 ms
这并不意味着结果与xslt处理器相同。