В этом нет ничего странного - это ожидаемое поведение любого XSLT 1.0-совместимого процессора.
Объяснение :
Переменная $nodeset
определена как:
<xsl:variable name="nodeset" select="extfn:node-set($resultTreeFragment)"/>
в XSLT 1.0 содержит полный xml документ - узел документа, обозначенный в XPath 1.0 как /
.
Таким образом,
<xsl:apply-templates select="$nodeset" mode="AParticularMode">
<xsl:with-param name="paramA" select="'valueA'"/>
</xsl:apply-templates>
Применит шаблон, соответствующий дереву (узел документа /
) в указанном режиме, если такой шаблон существует. В вашем случае такого шаблона не существует. Поэтому применяется встроенный шаблон XSLT 1.0 для /
(который относится к каждому режиму ).
Текст встроенного шаблона можно найти в spec :
<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>
согласно спецификации:
" Существует также встроенное правило шаблона для каждого режима, которое позволяет продолжить рекурсивную обработку в том же режиме при отсутствии успешного сопоставления с шаблоном явным правилом шаблона в таблице стилей. Это правило шаблона применяется к обоим узлы элементов и корневой узел. Ниже показан эквивалент правила встроенного шаблона для режима m .
<xsl:template match="*|/" mode="m">
<xsl:apply-templates mode="m"/>
</xsl:template>
"
Конечно, встроенный шаблон ничего не знает о вашем параметре $paramA
и не передает его в примененные шаблоны.
Таким образом, наконец, ваш шаблон, соответствующий p1:foo"
в mode="AParticularMode"
, выбран для обработки. Ничто не передается в качестве значения для параметра, поэтому оно не имеет значения - таким образом, <xsl:value-of>
не производит ни одного символа или узла.
Чтобы исправить эту проблему, просто добавьте шаблон, соответствующий /
, и в режиме "AParticularMode"
:
<xsl:template match="/" mode="AParticularMode">
<xsl:param name="paramA"/>
<xsl:apply-templates mode="AParticularMode">
<xsl:with-param name="paramA" select="$paramA"/>
</xsl:apply-templates>
</xsl:template>
и теперь вы получите желаемый результат.
В XSLT 2.0 (Saxon 9) вы наблюдаете другое поведение , потому что встроенные шаблоны в XSLT 2.0 по определению ретранслируют все параметры, с которыми они были применены - см. XSLT 2.0 Spec :
"Если встроенное правило вызывалось с параметрами, эти параметры
передаются в неявной инструкции xsl: apply-templates. "