2015-01-18 3 views
1

ПроблемаXSL: Как я могу сортировать трехзначное дефинированное значение?

Я пытаюсь сортировать по всей стоимости правила/@ идентификатор, где значение @Id является три значения, дефис строка, как это «1-10-12» или «10- 15-2" . Я пробовал конвертировать в число, и я пробовал форматировать номер, но не повезло.

Результат выборка кода производится только по самым левым разрядам, субактериальные значения не соответствуют порядку.

источник XML:

<rule-mapping name="C"> 
    <rule id="0-1-1"> 
     <checker id="checker1"/> 
     <checker id="checker2"/> 
    </rule> 
    <rule id="0-1-10"> 
     <checker id="checker3"/> 
    </rule> 
    <rule id="0-1-11"> 
     <checker id="checker4"/>   
    </rule> 
    <rule id="15-1-2"> 
     <checker id="checker5"/>   
    </rule> 
    <rule id="0-1-12"> 
     <checker id="checker6"/>   
    </rule> 
</rule-mapping> 

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

<tbody> 
    <xsl:for-each select="rule-mapping/rule"> 
     <xsl:sort select="substring-before(@id, '-')" data-type="number"/> 
     <xsl:sort select="substring-after(@id, '-')" data-type="number"/> 

      <row> 
       <entry> 
       <xsl:value-of select="@id"/>                 
       </entry> 
       <entry> 
       <xsl:for-each select="checker"> 
       <p> 
       <codeph><xsl:value-of select="@id"/></codeph><xsl:text>&#160;</xsl:text> 

       </p> 
       </xsl:for-each>          
       </entry>         
      </row>       
      <xsl:text>&#xA;</xsl:text> 
    </xsl:for-each> 
</tbody> 

Ожидаемый результат:

<row> 
     <entry>0-1-1</entry> 
     <entry> 
     <p><codeph>checker1</codeph> </p> 
     <p><codeph>checker2</codeph> </p> 
     </entry> 
    </row> 
    <row> 
     <entry>0-1-10</entry> 
     <entry> 
     <p> 
      <codeph>checker3</codeph> </p> 
     </entry> 
    </row> 
    <row> 
     <entry>0-1-11</entry> 
     <entry> 
     <p> 
      <codeph>checker4</codeph> </p> 
     </entry> 
    </row> 
    <row> 
     <entry>0-1-12</entry> 
     <entry> 
     <p> 
      <codeph>checker6</codeph> </p> 
     </entry> 
    </row> 
    <row> 
     <entry>15-1-2</entry> 
     <entry> 
     <p> 
      <codeph>checker5</codeph> </p> 
     </entry> 
    </row> 

Спасибо заблаговременно.

ответ

1

Вы имеете право идею, но вы должны принять это один шаг дальше:

<xsl:sort select="substring-before(@id, '-')" data-type="number"/> 
<xsl:sort select="substring-before(substring-after(@id, '-'), '-')" data-type="number"/> 
<xsl:sort select="substring-after(substring-after(@id, '-'), '-')" data-type="number"/> 

С теми, три xsl:sort S вместе, он должен разобраться, как вы хотите.

+0

Конечно! Я не мог понять, как получить каждую часть строки. Спасибо. –

1

В духе XSLT 2.0/XPath 2.0, я хотел бы использовать один <xsl:sort/> так:

<xsl:sort select= 
    "for $n1 in xs:integer(tokenize(@id, '-')[1]), 
     $n2 in xs:integer(tokenize(@id, '-')[2]), 
     $n3 in xs:integer(tokenize(@id, '-')[3]) 
     return 
     10000*$n1 + 100*$n2 +$n3 
    "/> 

Полная трансформация становится:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:template match="/*"> 
    <xsl:apply-templates select="rule"> 
     <xsl:sort select= 
     "for $n1 in xs:integer(tokenize(@id, '-')[1]), 
      $n2 in xs:integer(tokenize(@id, '-')[2]), 
      $n3 in xs:integer(tokenize(@id, '-')[3]) 
      return 
      10000*$n1 + 100*$n2 +$n3 
     "/> 
     </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="rule"> 
     <row> 
     <entry> 
      <xsl:value-of select="@id"/>                 
     </entry> 
     <entry> 
      <xsl:apply-templates select="checker"/> 
     </entry>         
     </row>       
     <xsl:text>&#xA;</xsl:text> 
    </xsl:template> 

    <xsl:template match="checker"> 
    <p> 
     <codeph><xsl:value-of select="@id"/></codeph><xsl:text>&#160;</xsl:text> 
    </p> 
    </xsl:template> 
</xsl:stylesheet> 

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

<rule-mapping name="C"> 
    <rule id="0-1-1"> 
     <checker id="checker1"/> 
     <checker id="checker2"/> 
    </rule> 
    <rule id="0-1-10"> 
     <checker id="checker3"/> 
    </rule> 
    <rule id="0-1-11"> 
     <checker id="checker4"/>   
    </rule> 
    <rule id="15-1-2"> 
     <checker id="checker5"/>   
    </rule> 
    <rule id="0-1-12"> 
     <checker id="checker6"/>   
    </rule> 
</rule-mapping> 

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

<row> 
    <entry>0-1-1</entry> 
    <entry> 
     <p> 
     <codeph>checker1</codeph> </p> 
     <p> 
     <codeph>checker2</codeph> </p> 
    </entry> 
</row> 
<row> 
    <entry>0-1-10</entry> 
    <entry> 
     <p> 
     <codeph>checker3</codeph> </p> 
    </entry> 
</row> 
<row> 
    <entry>0-1-11</entry> 
    <entry> 
     <p> 
     <codeph>checker4</codeph> </p> 
    </entry> 
</row> 
<row> 
    <entry>0-1-12</entry> 
    <entry> 
     <p> 
     <codeph>checker6</codeph> </p> 
    </entry> 
</row> 
<row> 
    <entry>15-1-2</entry> 
    <entry> 
     <p> 
     <codeph>checker5</codeph> </p> 
    </entry> 
</row> 
Смежные вопросы