Я пытаюсь использовать значение в определенном теге в качестве имени переменной. Но при преобразовании системы xml выдается необъявленная переменная в исключении выражения XPath.
Мой XML-файл
<request>
<entityType>individual</entityType>
</request>
И файл Xslt
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns:xs = "http://www.w3.org/2001/XMLSchema"
xmlns:math = "http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes = "xs math"
version = "3.0">
<xsl:param name = "individual" static = "yes" as = "xs:string" select = "'1'"/>
<xsl:param name = "legal" static = "yes" as = "xs:string" select = "'2'"/>
<xsl:template match = "/*">
<xsl:param name = "entity" as = "xs:string" select = "concat('$',entityType)"/>
<xsl:variable name = "input" as = "xs:string">
<xsl:evaluate xpath = "$entity"/>
</xsl:variable>
<HTML><TITLE><xsl:value-of select = "$input"/></TITLE></HTML>
</xsl:template>
</xsl:stylesheet>
я ожидаю результата как
<HTML><TITLE>1</TITLE></HTML>
Но я получаю сообщение «Статическая ошибка в выражении XPath, указанном в xsl:evaluate: необъявленная переменная в выражении XPath».





Если вы прочитаете https://www.w3.org/TR/xslt-30/#dynamic-xpath, то вы обнаружите, что там четко указано: «Переменные, объявленные в таблице стилей в элементах xsl:variable или xsl:param, не входят в область видимости внутри целевое выражение.». Вам придется использовать xsl:with-param внутри xsl:evaluate и/или with-params на xsl:evaluate, чтобы объявить нужные вам параметры.
<xsl:evaluate xpath = "$entity" with-params = "map{ QName('', 'individual') : $individual }"/>
Как указано в вашем комментарии, вы хотите сопоставить определенные значения цвета строки с целочисленными значениями цвета, что может быть возможно в XSLT 3 с помощью карты, например. с вводом
<colors>
<color>red</color>
<color>green</color>
</colors>
и XSLT 3.0, например.
<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
version = "3.0"
xmlns:xs = "http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes = "#all"
expand-text = "yes">
<xsl:param name = "color-map"
as = "map(xs:string, xs:integer)"
select = "map {
'red' : 1,
'green' : 2
}"/>
<xsl:template match = "color">
<xsl:copy>{$color-map(.)}</xsl:copy>
</xsl:template>
<xsl:mode on-no-match = "shallow-copy"/>
</xsl:stylesheet>
вы получите результат, например.
<colors>
<color>1</color>
<color>2</color>
</colors>
Пример онлайн-скрипки .
@MartinHonnen прав в своем объяснении, почему это не работает, но, отойдя от этого, мне интересно, чего вы на самом деле пытаетесь достичь? Что произойдет, если исходный XML-документ содержит значение, отличное от «индивидуального» или «юридического»? Если это единственные два значения, которые таблица стилей может правильно обработать, наверняка есть более простой способ сопоставить их с целыми числами 1 и 2?
Я действительно не знаю, в чем ваша проблема, но подозреваю, что xsl:evaluate не является правильным решением.
это гораздо более простая версия моих настоящих xml и xslt. У меня есть некоторые эталонные значения, например цвета. Входящий запрос имеет цвет <color> красный </color>, и для каждого цвета в системе имеются целочисленные значения. Система принимает для цветов только целые значения. поэтому мне нужно сопоставить цвета и создать с его помощью новый XML
Что ж, использование xsl:evaluate мне кажется дорогим и хрупким подходом. Гораздо лучше и дешевле читать файл данных (XML или JSON), который сопоставляет названия цветов с целыми числами.
Если вы прочитаете w3.org/TR/xslt-30/#dynamic-xpath, то обнаружите, что там четко указано: «Переменные, объявленные в таблице стилей в элементах
xsl:variableилиxsl:param, не входят в область действия целевого выражения». Вам придется использоватьxsl:with-paramвнутриxsl:evaluateи/илиwith-paramsнаxsl:evaluate, чтобы объявить нужные вам параметры.