2017-04-21 21 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

請測量並分享結果。 –

相關問題