2017-04-21 19 views
0

我很好奇撒克逊XSLT解析器是否会优化隧道参数传递 - 如果使用相同的值,它会被重新创建吗?或者,它是否使用当前副本?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元素是否有区别。

回答

2

当Saxon调用模板时,它首先创建一个新的XPathContext对象;这对应于XPath和XSLT规范中定义的“动态上下文”(除了在执行范围内不发生变化的部分,例如当前日期/时间外)。新的XPathContext对象复制调用者上下文的某些方面并重新初始化其他部分(如本地变量)。

XPathContext对象包含一个名为tunnelParams的字段,其值是一个ParameterSet;这是一组名称/值对,而不像HashMap。当调用模板时,将创建一个新的ParameterSet对象,其中包含调用方传递的ParameterSet中条目的联合以及被调用者声明的新的通道参数。参数集中的条目被复制,但是当然这些值本身不需要被复制,因为所有的XDM值都是不可变的。

话虽如此,我在理解你的问题意味着什么时遇到了一些麻烦。如果将隧道参数“重置”为现有值(例如,全局变量中的值),那么ParameterSet将只包含对该值的引用。如果你设置它使用一些计算,如

<xsl:with-param name="tun-par" select="23 to 50"/> 

然后它不会识别新值是否与以前的值相同。

+0

谢谢凯博士。根据你的解释,我预计在我的代码中重新声明隧道参数的代价应该很低。 – dave

+0

请测量并分享结果。 –

相关问题