Как я могу применить шаблон xslt к строке?
Учитывая шаблон, используемый для построения некоторого HTML вокруг значения, я хочу передать строку, а не набор узлов. В качестве примера я хочу объединить некоторые значения и передать их в шаблон. Как я могу достичь такого рода вещей?
<xsl:template match="text()" mode="kvp-print-single">
<tr>
<td colspan="3"><xsl:value-of select="."/></td>
</tr>
</xsl:template>
...
<xsl:apply-templates select="concat=(haba/hiba:text(), ' - ', huba/baba:text())" mode="kvp-print-single"/>
ErrorMsg: файл XML или таблицы стилей недействителен!
Исключение: System.Xml.Xsl.XsltException: выражение должно вычисляться как набор узлов.
3 ответа
Если целью является повторное использование кода, чтобы использовать шаблон в нескольких местах, то вы можете дать вашему шаблону имя (в дополнение к совпадению с шаблоном) и задать для него параметр по умолчанию
<xsl:template match="text()" name="kvp-print-single" mode="kvp-print-single">
<xsl:param name="text" select="." />
<tr>
<td colspan="3"><xsl:value-of select="$text"/></td>
</tr>
</xsl:template>
Затем просто используйте xsl:call-template, чтобы вызвать его со связанной строкой в качестве параметра.
<xsl:call-template name="kvp-print-single">
<xsl:with-param name="text" select="concat(haba/hiba:text(), ' - ', huba/baba:text())" />
</xsl:call-template>
Обратите внимание, что при сопоставлении с использованием xsl: apply-templates шаблон все равно будет соответствовать узлам text() обычным образом.
Вы можете использовать call-template и именованный шаблон, а не apply-templates, таким образом:
<xsl:template name="kvp-print-single">
<xsl:param name="theValue"/>
<tr>
<td colspan="3"><xsl:value-of select="$theValue"/></td>
</tr>
</xsl:template>
<xsl:call-template name="kvp-print-single">
<xsl:with-param name="theValue" select="concat(haba/hiba:text(), ' - ', huba/baba:text())"/>
</xsl:call-template>
Смысл применения шаблонов состоит в том, чтобы взять набор узлов и применить наиболее подходящий шаблон к каждому узлу по очереди. Шаблоны вызовов и именованные шаблоны позволяют разбить ваш XSLT на более управляемые куски, не меняя контекст.
Вы не можете "передать строку, а не набор узлов", потому что шаблоны не вызываются как функции. В XSLT не код контролирует порядок выполнения, а данные - путем сопоставления шаблонов. Можно использовать именованные шаблоны, которые можно вызывать вместо сопоставления, но для передачи значений можно использовать параметры для каждого шаблона.
В вашем случае вам даже не нужно это делать, так как вы можете адресовать текстовые части (учитывая, что haba/hiba - это адрес) примерно так:
<xsl:template match="some_element" mode="kvp-print-single">
<tr>
<td colspan="3">
<xsl:value-of select="concat=(/root/haba/hiba/text(), ' - ', /root/huba/baba/text())"/>
</td>
</tr>
</xsl:template>
Конечно, адрес должен быть правильным XPath (абсолютным или даже относительно соответствующего элемента).
@Mithon: другие ответы требуют параметров. Используйте столько модульных шаблонов, сколько вы хотите, но зачем вам добавлять параметры, если они вам не нужны?