(Отредактировано и успешно решено в ответ на комментарий; TL;DR: забыли пространство имен 'xsl' тега for-each - действительно неловко. Иногда ваша единственная цель в жизни - служить предупреждением для других , так что я исправляю свой вопрос с ответом)
пытаясь перебрать статические значения. лучший похожий вопрос, который я могу найти в поиске, это xslt-1.0 iterate over фиксированный список значений. но я просто не могу получить такое же поведение.
используя либо Firefox 82.0.3 (в сочетании с сервером nginx), либо Saxon 9.9.1.5 на моей машине, я получаю те же результаты. я изолировал код for-each, который ведет себя не так, как ожидалось. текущий документ, кажется, никогда не устанавливается в новый временный документ, на который указывает выбор для каждого.
я проверил использование for-each на нескольких сайтах, и я уверен, что упустил что-то простое. я просто не вижу этого. другие могут явно заставить это работать, а я по какой-то причине не могу. я не думал, что мне явно нужно использовать набор узлов в XSL 3, хотя попытка этого не дала лучших результатов. я попробовал метод XSL 1.0, указанный в связанных вопросах и ответах, и несколько других смежных методов.
XML
<?xml-stylesheet type="text/xsl" href="for-each-test.xsl" ?>
<Character xmlns:math="http://exslt.org/math" xmlns:xi="http://www.w3.org/2001/XInclude">
<abc>xyz</abc>
</Character>
XSL
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
xmlns:math="http://exslt.org/math"
extension-element-prefixes="exsl" >
<xsl:output method="html" version="4.01" indent="yes"/>
<xsl:output doctype-system="http://www.w3.org/TR/html4/strict.dtd"/>
<xsl:output doctype-public="-//W3C//DTD HTML 4.01//EN"/>
<xsl:variable name='var'>
<type>enhancement</type>
<type>inherent</type>
<type>enlargement</type>
</xsl:variable>
<xsl:template match='/'>
<html><head></head><body>
<!-- this was my original technique, which omitted 'xsl:'
<for-each select="document('')//xsl:variable[@name='var']/*">
name[<xsl:value-of select='name(.)'/>] = [<xsl:value-of select='.'/>]<br/>
</for-each>
-->
<!-- these techniques work -->
<xsl:for-each select="document('')//xsl:variable[@name='var']/*">
name[<xsl:value-of select='name(.)'/>] = [<xsl:value-of select='.'/>]<br/>
</xsl:for-each>
<xsl:for-each select='exsl:node-set($var)//type'>
name[<xsl:value-of select='name(.)'/>] = [<xsl:value-of select='.'/>]<br/>
</xsl:for-each>
<!-- other incorrect techniques i tried;
they don't work even with tags corrected;
didn't really expect these to work;
was grasping at straws with these, really -->
<!--
<xsl:for-each select='exsl:node-set($var)'>
name[<xsl:value-of select='name(.)'/>] = [<xsl:value-of select='.'/>]<br/>
</xsl:for-each>
<xsl:for-each select='$var//type'>
name[<xsl:value-of select='name(.)'/>] = [<xsl:value-of select='.'/>]<br/>
</xsl:for-each>
<xsl:for-each select='$var/*'>
name[<xsl:value-of select='name(.)'/>] = [<xsl:value-of select='.'/>]<br/>
</xsl:for-each>
<xsl:for-each select='$var'>
name[<xsl:value-of select='name(.)'/>] = [<xsl:value-of select='.'/>]<br/>
</xsl:for-each>
-->
</body></html>
</xsl:template>
</xsl:stylesheet>
Пример вывода цикла For-Each До исправления
name[] = [ xyz ]
Желаемый результат и пример вывода цикла For-Each После исправления
name[type] = [enhancement]
name[type] = [inherent]
name[type] = [enlargement]
<for-each select="...">
— это элемент буквального результата, а не инструкция XSLT. Чтобы обработать набор узлов, вам нужно использовать<xsl:for-each select="...">
. -- П.С. Браузер не является хорошей средой для тестирования. Также имейте в виду, что браузеры поддерживают только XSLT 1.0. - person michael.hor257k   schedule 17.11.2020