2010-12-12 5 views
7

Я хотел использовать динамическое имя переменной в инструкции select в xslt.можно использовать имя динамической переменной в инструкции select в xslt?

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:template match="/"> 
    <xsl:variable name="input" select="input/message" /> 
    <xsl:variable name="Name" select="'MyName'" /> 
    <xsl:variable name="Address" select="MyAddress" /> 
    <xsl:variable name="output" select="concat('$','$input')" /> <!-- This is not working --> 
    <output> 
     <xsl:value-of select="$output" /> 
    </output> 
</xsl:template> 

Возможные значения для "входа" переменная 'Имя' или 'адрес'. Оператор select выходной переменной должен иметь имя динамической переменной, основанное на значении входной переменной. Я не хочу использовать xsl: select. Я хотел бы выбрать значение динамически. Пожалуйста, предоставьте мне решение.

Спасибо, dhinu

+0

Хорошего вопрос, +1. См. Мой ответ для полного и короткого решения. :) –

ответ

11

XSLT 1.0 и XSLT 2.0 не имеют динамическую оценку.

Решение вашей проблемы:

Это преобразование:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:my="my:my"> 
<xsl:output method="text"/> 

<my:values> 
    <name>MyName</name> 
    <address>MyAdress</address> 
</my:values> 

<xsl:template match="/"> 
    <xsl:variable name="vSelector" 
    select="input/message"/> 
    <xsl:value-of select= 
    "document('')/*/my:values/*[name()=$vSelector]"/> 
</xsl:template> 
</xsl:stylesheet> 

при нанесении на следующий документ XML:

<input> 
    <message>address</message> 
</input> 

производит хотел, правильный результат:

MyAdress 

когда же преобразование применяется на этот XML-документ:

<input> 
    <message>name</message> 
</input> 

снова разыскиваемый, правильный результат получается:

MyName 

Наконец: Если вы не хотите использовать функцию document(), но пойдет на использование функции расширения xxx:node-set(), тогда это решение (похоже, похожее на то, что вам нужно), где вы можете проконсультироваться с документацией XSLTпроцессора для точного пространства имен расширения:

<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:variable name="vValues"> 
    <name>MyName</name> 
    <address>MyAdress</address> 
</xsl:variable> 

<xsl:template match="/"> 
    <xsl:variable name="vSelector" 
    select="input/message"/> 
    <xsl:value-of select= 
    "ext:node-set($vValues)/*[name()=$vSelector]"/> 
</xsl:template> 
</xsl:stylesheet> 
+0

Спасибо! Это сработало для меня. Просто хочу знать, есть ли альтернативный способ без использования дополнительного пространства имен xmlns: my = "my: my"? – dhinu

+0

@dhinu: Рад, что мой ответ был полезен. На SO благодарность выражается путем принятия ответа (нажав на контрольную отметку рядом с ответом) :). Вы можете поместить '' в другой файл и снова получить доступ к нему с помощью функции 'document()'. В XSLT 1.0 вам обычно приходится использовать эту технику. Если элементы находятся в теле '' или '', они не могут быть доступны с помощью XPath напрямую, а функция расширения ('xxx: node-set()') необходима для применения сначала , В XSLT 2.0 можно напрямую получить элементы внутри '' или ''. –

+0

Можете ли вы предоставить пример доступа к элементам в элементе xsl: variable с помощью функции расширения (xxx: node-set())? (Im, использующий XSLT 1.0) – dhinu

0

Кроме @ хороший ответ Dimitre, за этот конкретный случай (выходное значение строки) можно также использовать:

<xsl:variable name="output" 
       select="concat(substring($Name, 1 div ($input = 'Name')), 
          substring($Address, 1 div ($input = 'Address')))"/>