2016-05-04 2 views
1

Я пытаюсь получить value-of $deal/total_price. В первом блоке я могу получить ценность, и все работает отлично. Во втором блоке, где я использую value-of для установки переменной с именем deal, я получаю сообщение об ошибке при попытке отобразить $deal/total_price. Как я могу вернуть $deal/total_price, используя настройку во втором блоке?Ошибка неверного типа XSL - установка переменной с использованием значения

Работы:

<xsl:variable name="deal" select="/webpage/results/cars/*[partner_name = $company_name and vehicle_class_description = $vehicle_class_description_full]" />   
<xsl:value-of select="$deal/total_price"/> 

не работает:

<xsl:variable name="deal"> 
    <xsl:value-of select="/webpage/results/cars/*[partner_name = $company_name and vehicle_class_description = $vehicle_class_description_full]"/> 
</xsl:variable> 
<xsl:value-of select="$deal/total_price"/> 

Я получаю следующие ошибки/предупреждения:

Warning: XSLTProcessor::transformToXml(): Invalid type 
Warning: XSLTProcessor::transformToXml(): runtime error: 
Warning: XSLTProcessor::transformToXml(): XPath evaluation returned no result 
+0

Может быть, вы должны объяснить * реальный * проблема здесь - то, что именно вы хотите достичь здесь, которые не могут быть выполнены с использованием либо 'select' непосредственно из' XSL: копирования of'. –

+0

Моя конечная цель - изменить значение сделки с переменной в зависимости от разных флагов. Пример: if (pay_now == true) else Michael

+0

Используя XSL 1.0, что было бы лучшим способом изменить значение переменной, используя условные выражения, не вызывая ошибку ошибки? – Michael

ответ

0

Проблема в том, что вторая версия возвращает RTF (результирующий фрагмент дерева), а не набор узлов, такой как первая версия. Запрос XPath не может быть применен к RTF, его можно применять только к набору узлов.

Объяснение разницы can be found here at Oracle.

В XSLT-1.0 вы не можете избежать этого, как это explained here at StackOverflow.

цитирую по ссылке Oracle:

Результат фрагмент дерева эквивалентен набору узлов, который содержит только корневой узел.
Вы не можете применять такие операторы, как «/», «//» или предикат на фрагментах результирующего дерева. Они применимы только для типов данных с набором узлов.

Решение (возможно, самое простое) будет использовать XSLT-2.0, поскольку в XSLT-2.0 все переменные являются наборами узлов и RTF-файлами.

+0

Есть ли способ изменить значение переменной, используя выражения if/else? Пример <если флаг = истина> множество переменного истинной остального множества переменной к ложному Michael

1

С <xsl:variable name="deal" select="/webpage/results/cars/*[partner_name = $company_name and vehicle_class_description = $vehicle_class_description_full]" /> тип переменной определяется путем вычисления выражения XPath XPath, которое возвращает набор узлов в XSLT/XPath 1.0. Затем вы можете выполнить XPath-навигацию по набору узлов, например, выбрать дочерние узлы.

С

<xsl:variable name="deal"> 
    <xsl:value-of select="/webpage/results/cars/*[partner_name = $company_name and vehicle_class_description = $vehicle_class_description_full]"/> 
</xsl:variable> 

переменная типа представляет собой фрагмент результирующего дерева, содержащий текстовый узел со значением строки первого узла, выбранного внутренним value-of. С переменным фрагмента результирующего дерева типа вы не можете использовать любую навигацию по XPath, вы можете вывести его строковое значение, используя value-of или его фрагмент дерева, используя copy-of. Если вы хотите использовать XPath-навигацию, сначала вам нужно использовать exsl:node-set или аналогично преобразовать фрагмент дерева результатов в набор узлов, но даже если вы сделаете это для своего второго образца, вы получите exsl:node-set($deal) набор узлов с документом узел, содержащий текстовый узел. Таким образом, если вы хотите иметь переменный, содержащие узлы в XSLT 1.0 вам нужно использовать

<xsl:variable name="deal-rtf"> 
    <foo> 
    <bar>...</bar> 
    </foo> 
</xsl:variable> 
<xsl:variable name="deal" select="exsl:node-set($deal-rtf)" xmlns:exsl="http://exslt.org/common"/> 

<xsl:value-of select="$deal/foo/bar"/> 

Некоторых XSLT 1.0 процессоров (в частности, различные версии MSXML, как используемые IE или Краем и XslTransform в рамках .NET) не поддержка exsl:node-set, а скорее аналогичная функция в проприетарном пространстве имен (т.е.<xsl:variable name="deal" select="ms:node-set($deal-rtf)" xmlns:ms="urn:schemas-microsoft-com:xslt"/>).

Внутри xsl:variable вы можете, конечно, использовать xsl:choose, например.

<xsl:variable name="deal-rtf"> 
    <xsl:choose> 
    <xsl:when test="..."> 
     <xsl:copy-of select="/webpage/results/cars/*[partner_name = $company_name and vehicle_class_description = $vehicle_class_description_full and pay_now = 'Y']"/> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:copy-of select="webpage/results/cars/*[partner_name = $company_name and vehicle_class_description = $vehicle_class_description_full]"/> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:variable> 

<xsl:variable name="deal" select="exsl:node-set($deal-rtf)" xmlns:exsl="http://exslt.org/common"/> 

<xsl:value-of select="$deal/total_price"/> 
Смежные вопросы