我很好奇 Saxon XSLT 解析器是否会优化隧道参数传递 - 如果使用相同的值,是否会重新创建?或者,它是否使用当前副本?
我不确定是否有必要提供一个示例,但我已尝试在下面说明我的特定用例。
示例输入 xml:
<formDefinition sysid="1">
<subform sysid="2">
<subform layoutGrid="8" sysid="3">
<field weight="2" sysid="4">
<bind match="none" />
<type><date /></type>
</field>
</subform>
</subform>
</formDefinition>
提供一些上下文 - 子表单元素类似于 HTML DIV 元素,字段元素类似于 HTML INPUT 元素。layoutGrid 属性可以由子表单设置或覆盖,并由后代使用,例如字段。
我的实际样式表和“formDefinition”要大得多,使用了许多隧道参数和许多难以分区的相互关联的设置,因此很难避免将参数重置为其现有值。
我已经尝试在下面给出一个一般流程来说明我如何只设置一个隧道参数。
示例样式表 -
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[@sysid]">
<xsl:apply-templates select="." mode="render" />
</xsl:template>
<xsl:template match="/formDefinition" mode="render">
<xsl:copy>
<xsl:next-match />
</xsl:copy>
</xsl:template>
<xsl:template match="subform" mode="render">
<xsl:param name="pLayoutGrid" as="xs:decimal" tunnel="yes" />
<xsl:copy>
<xsl:attribute name="effLayoutGrid" select="$pLayoutGrid" />
<xsl:next-match />
</xsl:copy>
</xsl:template>
<xsl:template match="field" mode="render">
<xsl:param name="pLayoutGrid" as="xs:decimal" tunnel="yes" />
<xsl:copy>
<xsl:attribute name="effLayoutGrid" select="$pLayoutGrid" />
<xsl:next-match />
</xsl:copy>
</xsl:template>
<xsl:template match="*" mode="render">
<xsl:apply-templates select="*[not(@sysid)]" />
<xsl:call-template name="step" />
</xsl:template>
<xsl:template name="step">
<xsl:apply-templates select="*[@sysid]">
<xsl:with-param name="pLayoutGrid" as="xs:decimal" tunnel="yes">
<xsl:apply-templates select="." mode="layoutGrid" />
</xsl:with-param>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="/formDefinition" mode="layoutGrid">
<xsl:sequence select="xs:decimal(12)" />
</xsl:template>
<xsl:template match="subform" mode="layoutGrid">
<xsl:param name="pLayoutGrid" as="xs:decimal" tunnel="yes" />
<!-- potentially resetting the same value here -->
<xsl:sequence select="(@layoutGrid, $pLayoutGrid)[1]" />
</xsl:template>
<xsl:template match="field" mode="layoutGrid">
<xsl:param name="pLayoutGrid" as="xs:decimal" tunnel="yes" />
<!-- setting value to current value -->
<xsl:sequence select="$pLayoutGrid" />
</xsl:template>
</xsl:stylesheet>
输出:
<formDefinition>
<subform effLayoutGrid="12">
<subform effLayoutGrid="12">
<field effLayoutGrid="8">
<bind match="none" />
<type>
<date />
</type>
</field>
</subform>
</subform>
</formDefinition>
我的问题是,在示例的上下文中 - 重置 pLayoutGrid 隧道参数是否实际上创建了一个新的“对象”,还是在将值设置回其当前值时重用了当前的对象?
在我的完整代码中,我也有 xml 元素/树的隧道参数。我提到这一点是因为我想知道“基本”类型和 xml 元素之间是否存在差异。
当 Saxon 调用模板时,它首先创建一个新的 XPathContext 对象;这对应于 XPath 和 XSLT 规范中定义的“动态上下文”(除了在执行范围内不变的部分,如当前日期/时间)。新的 XPathContext 对象复制调用者上下文的某些方面并重新初始化其他部分(如局部变量)。
XPathContext 对象包含一个名为 tunnelParams 的字段,其值为 ParameterSet;这是一组名称/值对,类似于 HashMap。当模板被调用时,会创建一个新的 ParameterSet 对象,其中包含调用者传递的 ParameterSet 中的条目和被调用者声明的新隧道参数的联合。ParameterSet 中的条目被复制,但当然不需要复制值本身,因为所有 XDM 值都是不可变的。
话虽如此,我在理解您的问题的确切含义时遇到了一些麻烦。如果您将隧道参数“重置”为现有值(例如,全局变量中的值),则 ParameterSet 将仅包含对该值的引用。如果你使用一些计算来设置它,比如
<xsl:with-param name="tun-par" select="23 to 50"/>
那么它不会认识到新值与某些先前值相同。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句