Как реализовать условие «если еще, если еще» в XSLT - PullRequest
21 голосов
/ 02 марта 2011

Можно ли реализовать "если еще, если еще" в xsl?например, у меня есть данные:

<document>
    <line>
        <name>MAR111</name>
        <value>1</value>
    </line>

    <line>
        <name>MAR111</name>
        <value>3</value>
    </line>
    <line>
        <name>MEA111</name>
        <value>1</value>
    </line>
    <line>
        <name>MPR111</name>
        <value>1</value>
    </line>
    <line>
        <name>MEA111</name>
        <value>4</value>
    </line>
    <line>
        <name>MPR111</name>
        <value>2</value>
    </line>
</document>

Мне нужно получить три шаблона документов с тремя именами:

<document>
    <MAR>
        <name>MAR111</name>
        <number>1</number>
        <number>4</number>
    </MAR>
</document>
<document>
    <MEA>
        <name>MEA111</name>
        <number>1</number>
        <number>4</number>
    </MEA>
</document>
<document>
    <MPR>
        <name>MPR111</name>
        <number>1</number>
        <number>2</number>
    </MPR>
</document>

Я пытаюсь использовать «выбрать, когда» при применении шаблона, но возможноесть лучший способ:

<xsl:template match="/">
    <xsl:choose>
        <xsl:when test="/document/line/name='MEA111'">
            <xsl:apply-templates mode="MEA" select="/document"/>
        </xsl:when>
    </xsl:choose>
    <xsl:choose>
        <xsl:when test="/document/line/name='MPR111'">
            <xsl:apply-templates mode="MPR" select="/document"/>
        </xsl:when>
    </xsl:choose>
    <xsl:choose>
        <xsl:when test="/document/line/name='MAR111'">
            <xsl:apply-templates mode="MAR" select="/document"/>
        </xsl:when>
    </xsl:choose>
</xsl:template>

Ответы [ 7 ]

26 голосов
/ 02 марта 2011

На самом деле вы можете объединить их:

<xsl:template match="/">
    <xsl:choose>
        <xsl:when test="/document/line/name='MEA111'">
            <xsl:apply-templates mode="MEA" select="/document"/>
        </xsl:when>
        <xsl:when test="/document/line/name='MPR111'">
            <xsl:apply-templates mode="MPR" select="/document"/>
        </xsl:when>
        <xsl:when test="/document/line/name='MAR111'">
            <xsl:apply-templates mode="MAR" select="/document"/>
        </xsl:when>
    </xsl:choose>
</xsl:template>

РЕДАКТИРОВАТЬ: Петрас, после вашего разъяснения, кажется, что то, что вы хотите, еще проще:

<xsl:template match="/">
    <xsl:if test="/document/line/name='MEA111'">
       <xsl:apply-templates mode="MEA" select="/document"/>
    </xsl:if>
    <xsl:if test="/document/line/name='MPR111'">
        <xsl:apply-templates mode="MPR" select="/document"/>
    </xsl:if>
    <xsl:if test="/document/line/name='MAR111'">
        <xsl:apply-templates mode="MAR" select="/document"/>
    </xsl:if>
</xsl:template>
6 голосов
/ 02 марта 2011

Лучший способ - использовать отдельные шаблоны.

<xsl:template match="/document/line/name='MEA111'">
       <xsl:apply-templates mode="MEA" select="/document"/>
</xsl:template>

<xsl:template match="/document/line/name='MPR111'">
       <xsl:apply-templates mode="MPR" select="/document"/>
</xsl:template>

<xsl:template match="/document/line/name='MAR111'">
       <xsl:apply-templates mode="MAR" select="/document"/>
</xsl:template>

Еще меньше строк, и это более удобно для обслуживания.

5 голосов
/ 02 марта 2011

Нет, choose when - это xsl способ сказать if else. Нет лучшего способа

2 голосов
/ 06 декабря 2012

, если вы хотите реализовать всеобъемлющий провал (например, эквивалент «else»), вы должны использовать otherwise

2 голосов
/ 02 марта 2011

Эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="kLineByName" match="line" use="name"/>
    <xsl:template match="line[count(.|key('kLineByName',name)[1]) = 1]">
        <document>
            <xsl:element name="{substring(name,1,3)}">
                <xsl:copy-of select="name|key('kLineByName',name)/value"/>
            </xsl:element>
        </document>
    </xsl:template>
    <xsl:template match="text()"/>
</xsl:stylesheet>

Выход:

<document>
    <MAR>
        <name>MAR111</name>
        <value>1</value>
        <value>3</value>
    </MAR>
</document>
<document>
    <MEA>
        <name>MEA111</name>
        <value>1</value>
        <value>4</value>
    </MEA>
</document>
<document>
    <MPR>
        <name>MPR111</name>
        <value>1</value>
        <value>2</value>
    </MPR>
</document>
1 голос
/ 14 мая 2014

Вы имеете в виду что-то вроде:

<xsl:choose>
  <xsl:when test="name() = 'MAR111'">
    ... do something ...
  </xsl:when>
  <xsl:otherwise>
    ... do something as fallback ...
  </xsl:otherwise>
</xsl:choose>

BR Markus

0 голосов
/ 21 апреля 2017

Да, мы можем добиться чего-то, используя <xsl:choose><xsl:when>, но, если, иначе, условие также поддерживается в атрибуте @select другой конструкции xslt, например:

<xsl:value-of select="if (@geography = 'North America') then 
                 'Domestic car'
                else if (@geography = 'Europe') then 
                  'Import from Europe'
                else if (@geography = 'Asia') then 
                  &quot;It's from Asia&quot;
                (: If it's anything else :)
                else 
                   'We don''t know!'"/>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...