Оптимизирует ли процессор Saxon 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.


person dave    schedule 21.04.2017    source источник


Ответы (1)


Когда Saxon вызывает шаблон, он сначала создает новый объект XPathContext; это соответствует «динамическому контексту», определенному в спецификациях XPath и XSLT (за исключением частей, которые не меняются в пределах области выполнения, например, текущая дата / время). Новый объект XPathContext копирует некоторые аспекты контекста вызывающего и повторно инициализирует другие части (например, локальные переменные).

Объект XPathContext содержит поле с именем tunnelParams, значением которого является ParameterSet; это набор пар имя / значение, скорее похожий на HashMap. Когда шаблон вызывается, создается новый объект ParameterSet, содержащий объединение записей в ParameterSet, переданных вызывающей стороной, и новых параметров туннеля, объявленных вызываемым объектом. Записи в ParameterSet копируются, но, конечно, сами значения копировать не нужно, потому что все значения XDM неизменяемы.

Сказав это, мне трудно понять, что именно означает ваш вопрос. Если вы «сбрасываете» параметр туннеля на существующее значение (скажем, значение в глобальной переменной), тогда ParameterSet просто будет содержать ссылку на это значение. Если вы установите его с помощью некоторых вычислений, например

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

тогда он не распознает, что новое значение совпадает с некоторым предыдущим значением.

person Michael Kay    schedule 21.04.2017
comment
Спасибо, доктор Кей. Основываясь на вашем объяснении, я предполагаю, что стоимость повторного объявления параметра туннеля в моем коде будет низкой. - person dave; 22.04.2017
comment
Пожалуйста, измерьте это и поделитесь результатами. - person Michael Kay; 22.04.2017