Нет, шаблоны (в XSLT 1.0) не могут содержать ссылки на переменные / параметры .
Один из способов выполнить такую задачу будет выглядеть так: :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:param name="pAuthor" select="'David Perry'"/>
<xsl:key name="kBookaByAuthor" match="book"
use="@author"/>
<xsl:template match="/">
Books written by <xsl:value-of select="$pAuthor"/> :<xsl:text/>
<xsl:apply-templates
select="key('kBookaByAuthor', $pAuthor)"/>
</xsl:template>
<xsl:template match="book">
<!-- One can do more formatting here -->
<xsl:text>
 </xsl:text>
<xsl:value-of select="@title"/>
</xsl:template>
</xsl:stylesheet>
Когда это преобразование применяется к предоставленному документу XML :
<titles>
<book title="XML Today" author="David Perry"/>
<book title="XML and Microsoft" author="David Perry"/>
<book title="XML Productivity" author="Jim Kim"/>
<book title="XSLT 1.0" author="Albert Jones"/>
<book title="XSLT 2.0" author="Albert Jones"/>
<book title="XSLT Manual" author="Jane Doe"/>
</titles>
желаемый, правильный результат получается :
Books written by David Perry :
XML Today
XML and Microsoft
Обновление : в комментарии ОП уточняется, что:
" Я думал, что полностью указал свои требования в первоначальном вопросе.
Как я уже упоминал в своем вопросе и в моем первом комментарии, это будет
мне полезно увидеть подход для решения более чем одного
автор"
Вот решение, которое действительно использует ключи (обратите внимание, что «ключ» в ответе @ Flynn1179 не создает никакого индекса и является просто постоянной последовательностью строк - таким образом, функция key()
, использующая этот xsl:key
, фактически находит строку в списке строк - что является O (N), в отличие от, как правило, O (1) для поиска в истинном индексе):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common">
<xsl:output method="text"/>
<xsl:param name="pAuthors">
<x>David Perry</x>
<x>Jane Doe</x>
</xsl:param>
<xsl:variable name="vParams" select=
"ext:node-set($pAuthors)/*"/>
<xsl:key name="kBookByAuthor" match="book"
use="@author"/>
<xsl:template match="/">
Books written by : <xsl:text/>
<xsl:apply-templates select="$vParams"/>
<xsl:apply-templates select=
"key('kBookByAuthor', $vParams)"/>
</xsl:template>
<xsl:template match="book">
<!-- One can do more formatting here -->
<xsl:text>
 </xsl:text>
<xsl:value-of select="concat('"', @title, '"')"/>
</xsl:template>
<xsl:template match="x">
<xsl:if test="not(position() = 1)">, </xsl:if>
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>
Когда это преобразование применяется к предоставленному XML-документу (см. Выше), будет получен требуемый, правильный результат :
Books written by : David Perry, Jane Doe
"XML Today"
"XML and Microsoft"
"XSLT Manual"
Примечание : В этом решении используется функция Exslt node-set()
. Здесь это сделано только для удобства . При реальном использовании значение параметра указывается извне, и тогда функция ext:node-set()
не требуется.
Эффективность : Это решение использует истинную силу ключей в XSLT. Эксперимент, проведенный с использованием процессоров XSLT MSXML (3, 4 и 6), показывает, что при поиске 10000 авторов время преобразования с различными процессорами XSLT варьируется от: 32 мс до 45 мс.
Интересно, что решение, представленное @ Flynn1179, на самом деле не делает ключевой индекс, и для многих процессоров XSLT оно занимает (для того же числа (10000) авторов) от 1044мс до 5564мс :
MSXML3 : 5564 мс,
MSXML4 : 2526мс,
MSXML6 : 4867 мс,
AltovaXML : 1044мс.
Это значительно ниже производительности, которую можно получить при индексировании по настоящему ключу (от 32 до 45 мс).