Числовая переменная / параметр в XSLT

У меня есть этот XSLT:

<xsl:template match="/">

    <xsl:variable name="errorCount" select="count($orders/*[1]/cm:Error)" />

    <xsl:apply-templates select="@*|node()">
        <xsl:with-param name="errorCount" select="$errorCount" tunnel="yes" />
    </xsl:apply-templates>
</xsl:template>

<xsl:template match="status">
    <xsl:param name="errorCount" tunnel="yes" />
    <xsl:copy>
        <xsl:choose>
            <xsl:when test="$errorCount > 0">
                <xsl:text>ERROR</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text>OK</xsl:text>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:copy>
</xsl:template>

Туннелирование и все такое вроде работает, но преобразование не выполняется из-за следующей ошибки:

Обязательный тип элемента первого операнда '>' - числовой; предоставленное значение имеет тип элемента xs: string

Сначала у меня было объявление переменной в шаблоне, где она использовалась, а потом все заработало. Перенесено, потому что мне нужно использовать такое же количество и в других шаблонах.

Как / где я могу объявить, что эта переменная / параметр на самом деле является числом?


person Svish    schedule 19.02.2013    source источник
comment
Значение атрибута туннеля должно быть «да» или «нет», а не «истина» или «ложь». Вы показываете нам код, который выполняете?   -  person Michael Kay    schedule 19.02.2013
comment
ах, да, это ошибка, которую я обнаружил сразу после того, как спросил об этом. Также добавлена ​​функция number, чтобы она работала в тесте. Но завтра проверю атрибут as :)   -  person Svish    schedule 19.02.2013


Ответы (3)


Поскольку вы используете XSLT 2.0, вам также следует добавить атрибут as в свой xsl: param в шаблоне. Например (вам может потребоваться использовать другое значение as в зависимости от того, каким должно быть полученное число, например, если у вас будут значения с десятичными знаками; вам также потребуется исправить значение туннеля на точку Майкла Кея) :

<xsl:param name="errorCount" tunnel="yes" as="xs:integer" />

Преобразование завершится ошибкой, если его нельзя преобразовать в тип as (в данном случае в целое число). Решение Eero может выглядеть чище, потому что вам все равно придется проверять, не превышает ли значение нуля. Но поскольку вы используете XSLT 2.0, лучше всего ввести свои параметры / переменные.

person TddOrBust    schedule 19.02.2013
comment
Так что мне нужно as только на param или также на элементах with-param и variable? - person Svish; 19.02.2013
comment
Повсюду положить его без вреда. Однако наиболее важным местом является xsl: param, потому что там система не может определить тип для себя. - person Michael Kay; 19.02.2013
comment
Похоже, это сработало, когда я только что исправил проблему _1 _- ›_ 2_, но все равно принимаю ее, поскольку она отвечает на мой настоящий вопрос :) - person Svish; 20.02.2013

Вы можете использовать number() для преобразования строки в число:

<xsl:when test="number($errorCount) > 0">
  <xsl:text>ERROR</xsl:text>
</xsl:when>
person Eero Helenius    schedule 19.02.2013
comment
Это отлично работает, и сейчас я исправил это, но хочу сделать это правильно, поскольку не должно быть необходимости преобразовывать число в число, чтобы оно было числом: p - person Svish; 19.02.2013
comment
Не могу с вами не согласиться. :) Что касается того, чтобы все было правильно, я бы посоветовал взглянуть на ответ доктора Кея. - person Eero Helenius; 19.02.2013

Я подозреваю, что из-за того, что вы написали tunnel = "true", а не tunnel = "yes", тот факт, что вы вообще указали туннель, (неправильно) игнорируется, и параметру присваивается значение по умолчанию, равное нулю. длина строки.

person Michael Kay    schedule 19.02.2013
comment
Похоже, это действительно устранило проблему! Тем не менее принял ответ as, поскольку он фактически ответил на мой вопрос Как / где я могу объявить переменную / параметр числом. - person Svish; 20.02.2013