XSL диапазон от числа

Първо, трябва да призная, че съм начинаещ в XML, така че простете ми за глупавите въпроси.

Целта ми е да получа стойността на $majorGoal.

<xsl:variable name="variable">
  <xsl:value-of select="(../@attribute) * 100 />
</xsl:variable>
<xsl:variable name="minorGoal1">
  <xsl:choose>
    <xsl:when test="$variable &lt; -2">25</xsl:when>
    <xsl:when test="$variable &gt;= -2">20</xsl:when>
  <xsl:choose>
</xsl:variable>
<xsl:variable name="minorGoal2">
  <xsl:choose>
    <xsl:when test="$variable &lt; -2">40</xsl:when>
    <xsl:when test="$variable &gt;= -2">24</xsl:when>
  <xsl:choose>
</xsl:variable>
<xsl:variable name="minorGoal3">
  <xsl:choose>
    <xsl:when test="$variable &lt; -2">55</xsl:when>
    <xsl:when test="$variable &gt;= -2 and &lt; 4">50</xsl:when>
    <xsl:when test="$variable &gt;= 4">50</xsl:when>
  <xsl:choose>
<xsl:variable name="minorGoal4">
  <xsl:choose>
    <xsl:when test="$variable &lt; -2">80</xsl:when>
    <xsl:when test="$variable &gt;= -2 and &lt; 4">70</xsl:when>
    <xsl:when test="$variable &gt;= 4">60</xsl:when>
  <xsl:choose>
</xsl:variable>

<!-- I have 10 more similar variables  -->

<xsl:variable name="minorGoal">
<xsl:choose>
  <xsl:when test="$anotherVariable = 30">
    <xsl:value-of select="$minorGoal1"/>
  </xsl:when>
  <xsl:when test="$anotherVariable = 40">
    <xsl:value-of select="$minorGoal2"/>
  </xsl:when>
  <xsl:when test="$anotherVariable = 50">
    <xsl:value-of select="$minorGoal3"/>
  </xsl:when>
  <xsl:when test="$anotherVariable = 60">
    <xsl:value-of select="$minorGoal4"/>
  </xsl:when>

<!-- Another 10 more similar variables  -->

</xsl:choose>
</xsl:variable>

<xsl:variable name="majorGoal">
  <xsl:value-of select="$minorGoal"/>
</xsl:variable>

@attribute се отнася до изходния xml файл. $anotherVariable се дефинира като глобална променлива в същия xsl файл и е постоянна.

Проблемът е, че анализаторът връща грешка:

Очаквано изражение. $променлива >= -2 и -->‹‹-- 4

Мога да предположа, че проблемът е причинен от:

<xsl:when test="$variable &gt;= -2 and &lt; 4">50</xsl:when>

но как иначе да се опише диапазон от числа?


person Netop    schedule 27.01.2014    source източник


Отговори (3)


Както вече беше обяснено от Матиас, за да проверите дали дадена променлива е между -2 и 4, трябва да направите:

 test="$variable &gt;= -2 and $variable &lt; 4"

Идеята с choose обаче е, че първият тест, който връща true, прекратява процеса и връща съответния резултат. Това означава, че вместо:

<xsl:variable name="minorGoal4">
  <xsl:choose>
    <xsl:when test="$variable &lt; -2">80</xsl:when>
    <xsl:when test="$variable &gt;= -2 and $variable &lt; 4">70</xsl:when>
    <xsl:when test="$variable &gt;= 4">60</xsl:when>
  <xsl:choose>
</xsl:variable>

можете да напишете просто:

<xsl:variable name="minorGoal4">
  <xsl:choose>
    <xsl:when test="$variable &lt; -2">80</xsl:when>
    <xsl:when test="$variable &lt; 4">70</xsl:when>
    <xsl:otherwise>60</xsl:otherwise>
  <xsl:choose>
</xsl:variable>

което е едновременно по-лесно за четене и по-ефективно за изпълнение.

person michael.hor257k    schedule 27.01.2014

Наистина трябва да етикетирате XSLT въпросите като XSLT 1.0 или 2.0, тъй като отговорите много често са различни.

В XSLT 2.0 можете да кажете

test="$var = (25 to 40)"

въпреки че това поставя някои изисквания към оптимизатора, така че

test="$var ge 25 and $var le 40"

може да е по-безопасно.

Също така в XSLT 2.0 можете да опростите това

<xsl:variable name="minorGoal4">
  <xsl:choose>
    <xsl:when test="$variable &lt; -2">80</xsl:when>
    <xsl:when test="$variable &gt;= -2 and $variable &lt; 4">70</xsl:when>
    <xsl:when test="$variable &gt;= 4">60</xsl:when>
  <xsl:choose>
</xsl:variable>

до това:

<xsl:variable name="minorGoal4" select="
    if ($variable lt -2) then 80
    else if ($variable lt 4) then 70
    else 60"/>

с допълнителния бонус, че резултатът е число, а не фрагмент от дърво на резултатите, което вероятно ще бъде много по-ефективно.

person Michael Kay    schedule 27.01.2014

Опитайте се да споменете $variable и в двете части на И. Също така се уверете, че $variable наистина е число, а не низ или нетипизирана атомна.

Освен това, ако използвате XSLT 2.0, първият израз може да бъде съкратен до ge, което означава "равно или по-голямо от".

<xsl:when test="number($variable) ge -2 and number($variable) lt 4">
70
</xsl:when>

Пример за илюстрация на това:

Въвеждане на XML

<?xml version="1.0" encoding="utf-8"?>
<root>
   <number>6</number>
   <number>3</number>
</root>

Стилове

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="/root">
      <xsl:copy>
         <xsl:apply-templates/>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="number">
      <xsl:copy>
         <xsl:choose>
            <xsl:when test="number(.) ge -2 and number(.) lt 4">
               <xsl:text>YES</xsl:text>
            </xsl:when>
            <xsl:otherwise>
               <xsl:text>NO</xsl:text>
            </xsl:otherwise>
         </xsl:choose>
      </xsl:copy>
   </xsl:template>

</xsl:stylesheet>

Изход

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <number>NO</number>
   <number>YES</number>
</root>
person Mathias Müller    schedule 27.01.2014
comment
OP не казва дали това е XSLT 1.0 или 2.0 - ge и lt са само 2.0, докато операторите >= и <, използвани във въпроса, ще работят и в двете версии. - person Ian Roberts; 27.01.2014
comment
Благодаря, Иън, ще го кажа изрично. - person Mathias Müller; 27.01.2014