Во-первых, saxon:evaluate()
не подходит для работы.
Теперь, почему это не работает? Чтобы объявить значение $ oSel, вы сделали что-то вроде этого:
<xsl:value-of select="$compose//*[contains(@outputclass,$sel)]"/>
, который оценивает выражение в атрибуте select и возвращает его результат. Но затем вы передаете $ oSel в saxon:evaluate()
, что ожидает строку, содержащую выражение XPath. Я думаю, что вы пытаетесь связать переменную с выражением «$ compose // * [содержит (@ outputclass, $ sel)]», а не с результатом вычисления этого выражения. Для этого вам нужно написать
<xsl:value-of select="'$compose//*[contains(@outputclass,$sel)]'"/>
Обратите внимание на дополнительные кавычки; но теперь это не получится, потому что выражение, переданное saxon:evaluate()
, не может явно использовать переменные, такие как $compose
(есть механизм для передачи параметров, но вы не хотите туда идти).
В XSLT 3.0 saxon:evaluate
заменяется стандартной инструкцией xsl:evaluate
; но вы тоже этого не хотите.
Правильный механизм для использования здесь - функции высшего порядка .
В XSLT 3.0 вы можете написать
<xsl:for-each-group select="$compose//*[$predicate(.)]" group-by="$grouping-key(.)">
Где $predicate
и $grouping-key
- переменные, связанные с пользовательскими функциями. Вы можете связать эти переменные с помощью логики:
<xsl:variable name="predicate" as="function(element()) as xs:boolean">
<xsl:choose>
<xsl:when test="starts-with($from,'oclass-')">
<xsl:sequence select="function($n){contains($n/@outputclass,$sel)}"/>
</xsl:when>
<xsl:when test="starts-with($from,'node-')">
<xsl:sequence select="function($n){name($n)=$sel}"/>
</xsl:when>
</xsl:choose>
</xsl:variable>