Проблема в переменной:
<xsl:variable name="currNode" select="." />
Это связывает переменную с потоковым входным узлом, что недопустимо, потому что Саксон не может гарантировать, что ваш выбор из этого входного узла сделан "в правильном порядке";вы выбираете потомков / потомков этого узла по имени, и анализ стримабельности не может установить, что эти потомки выбираются в порядке их появления на входе.
Ответ на самом деле прост: измените переменную на
<xsl:variable name="currNode" select="copy-of(.)" />
Таким образом, каждый раз, когда вы нажимаете на элемент DR, Saxon будет читать поддерево, укорененное в этом элементе, и удерживать его как дерево в памяти.Поскольку переменная теперь является обычным узлом в памяти, а не потоковым узлом, нет никаких ограничений на то, как он используется.
Позвольте мне добавить еще пару комментариев к вашему коду.
* 1012Во-первых, конструкция
document('')
, которая была популярна в XSLT 1.0, теперь полностью устарела.Гораздо лучше поместить данные поиска в глобальную переменную и получить к ней прямой доступ, используя
<xsl:param name="fields" select="$fieldArray/*"/>
. Вызов document('')
действительно не удастся, если вы попытаетесь скомпилировать таблицу стилей и выполнить ее где-то, кроме оригиналарасположение исходного кода.
Во-вторых, код для вывода строки заголовка:
<xsl:for-each select="$fields">
<xsl:if test="position() != 1">
<xsl:value-of select="$delimiter"/>
</xsl:if>
<xsl:value-of select="." />
</xsl:for-each>
может быть упрощен до
<xsl:value-of select="$fields" separator="{$delimiter}"/>
Аналогично, код для строк данных:
<xsl:for-each select="$fields">
<xsl:if test="position() != 1">
<xsl:value-of select="$delimiter"/>
</xsl:if>
<xsl:value-of select="$currNode/*/*[name() = current()]" />
</xsl:for-each>
упрощается до
<xsl:value-of select="for $f in $fields return $currNode/*/*[name()=$f]"
separator="{$delimiter}"/>