我需要更多的澄清。。
根据这个问题的答案,XSLT变量很便宜!我的问题是:这句话对所有场景都有效吗?在4行代码中创建和销毁的即时变量并不麻烦,但在我看来,加载根节点或子实体确实是一种糟糕的做法。。
我有两个XSLT文件,设计用于相同的输入和输出需求:
XSLT1(没有不必要的变量):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<Collection>
<xsl:for-each select="CATALOG/CD">
<DVD>
<Cover>
<xsl:value-of select="string(TITLE)"/>
</Cover>
<Author>
<xsl:value-of select="string(ARTIST)"/>
</Author>
<BelongsTo>
<xsl:value-of select="concat(concat(string(COUNTRY), ' '), string(COMPANY))"/>
</BelongsTo>
<SponsoredBy>
<xsl:value-of select="string(COMPANY)"/>
</SponsoredBy>
<Price>
<xsl:value-of select="string(number(string(PRICE)))"/>
</Price>
<Year>
<xsl:value-of select="string(floor(number(string(YEAR))))"/>
</Year>
</DVD>
</xsl:for-each>
</Collection>
</xsl:template>
</xsl:stylesheet>
XSLT2(带有不必要的变量"root",其中加载了整个XML):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="root" select="."/>
<Collection>
<xsl:for-each select="$root/CATALOG/CD">
<DVD>
<Cover>
<xsl:value-of select="string(TITLE)"/>
</Cover>
<Author>
<xsl:value-of select="string(ARTIST)"/>
</Author>
<BelongsTo>
<xsl:value-of select="concat(concat(string(COUNTRY), ' '), string(COMPANY))"/>
</BelongsTo>
<SponsoredBy>
<xsl:value-of select="string(COMPANY)"/>
</SponsoredBy>
<Price>
<xsl:value-of select="string(number(string(PRICE)))"/>
</Price>
<Year>
<xsl:value-of select="string(floor(number(string(YEAR))))"/>
</Year>
</DVD>
</xsl:for-each>
</Collection>
</xsl:template>
</xsl:stylesheet>
方法2是实时存在的,实际上XML是几个KB到几个MB,在XSLT中,变量的使用也扩展到子实体。。
要提出改变方法的建议,我需要验证其背后的理论。
根据我对方法2的理解,系统在内存中一遍又一遍地重新加载XML数据(如果使用多个变量加载子实体,情况会变得最糟),从而减缓转换过程。
在这里发布这个问题之前,我使用定时器测试了两个XSLT的性能。第一种方法比第二种方法花费的时间少几毫秒。(我使用复制XML文件来测试两个XSL文件,以避免系统缓存的复杂性)。但系统缓存在这里可能会扮演巨大的混淆角色。。
尽管我有这样的分析,我仍然有一个问题在想!我们真的需要避免使用变量吗。就我的系统而言,修改实时XSLT文件以使用"方法-1"的价值有多大?
或者XSLT变量是否与其他编程语言不同(如果我不知道的话,请使用Incase)。。例如,当您执行select="."
时,XSLT变量实际上并不存储数据,但它们有点指向数据!或者类似的。。?AND HENCE毫不犹豫地继续使用XSLT变量。。
你对此有什么建议?
当前系统的快速信息:
- 主机编程语言或系统:Siebel(C++是后端代码)
- XSLT处理器:Xalan(除非明确使用Saxon)
我同意所做的评论,即您需要用特定的XSLT处理器来衡量性能。
但你的描述或期望,比如"方法2,系统正在内存中一遍又一遍地重新加载XML数据",对我来说似乎是错误的。XSLT处理器无论如何都会构建主输入XML文档的输入树,我无法想象任何使用<xsl:variable name="root" select="."/>
的实现会像再次完全加载文档一样,因为节点标识和生成id将不起作用。该变量将简单地保留对现有输入树的文档节点的引用。
当然,在您的示例中,如果您有一个输入文档和一个模板,而当前节点无论如何都是文档,那么使用您的变量是多余的。但是,在某些情况下,您需要存储主输入文档的文档节点,尤其是在处理多个文档时。