Иерархия множественных сортировок xsl

У меня есть структура XML, которая выглядит следующим образом -

<Root>
  <name rank = "1">ABC
     <name rank ="1">BCD</name>
  </name>
  <name rank ="0">XYZ
     <name rank ="1">BCD</name>
     <name rank ="3">YYZ</name>
     <name rank ="0">FEG</name>
     <name rank ="0">DEG</name>         
  </name>
</Root>

Я хочу преобразовать этот XML, сделав его копию, сохранив иерархию, и отсортировав его в следующем порядке: (1) По рангу (по возрастанию) (2) Если ранги равны, сортировать по имени (по возрастанию).

После преобразования структура должна выглядеть следующим образом.

<Root>      
      <name rank ="0">XYZ
         <name rank ="0">DEG</name>
         <name rank ="0">FEG</name>
         <name rank ="1">BCD</name>
         <name rank ="3">YYZ</name>         
      </name>
      <name rank = "1">ABC
         <name rank ="1">BCD</name>
      </name>
 </Root>

У меня есть следующий XSL, который не сохраняет иерархию или дает мне правильный вид. Может кто-нибудь помочь мне? Я впервые работаю с XSL и буду признателен за любую помощь или указатели в правильном направлении.

<xsl:template match="/*">

    <xsl:copy>
    <xsl:for-each select="//name">
        <xsl:sort select="@rank" data-type="number" order="ascending"/>
        <xsl:sort select="name" order="ascending" />
        <xsl:copy-of select="."/>
    </xsl:for-each> 
    </xsl:copy>
  </xsl:template>

1 ответ

Решение

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

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
  <Root>
    <xsl:apply-templates select="name">
     <xsl:sort select="@rank" data-type="number"/>
     <xsl:sort/>
    </xsl:apply-templates>
  </Root>
 </xsl:template>

 <xsl:template match="name">
  <name rank="{@rank}">
    <xsl:copy-of select="text()"/>
    <xsl:apply-templates select="name">
     <xsl:sort select="@rank" data-type="number"/>
     <xsl:sort/>
    </xsl:apply-templates>
  </name>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному документу XML:

<Root>
  <name rank = "1">ABC
     <name rank ="1">BCD</name>
  </name>
  <name rank ="0">XYZ
     <name rank ="1">BCD</name>
     <name rank ="3">YYZ</name>
     <name rank ="0">FEG</name>
     <name rank ="0">DEG</name>
  </name>
</Root>

дает желаемый, правильный результат:

<Root>
    <name rank="0">XYZ
        <name rank="0">DEG</name>
        <name rank="0">FEG</name>
        <name rank="1">BCD</name>
        <name rank="3">YYZ</name></name>
    <name rank="1">ABC
        <name rank="1">BCD</name></name>
</Root>

Пояснение:

Используя два xsl:sort инструкции. Приоритет операций сортировки соответствует порядку документа соответствующего xsl:sort инструкции.

Другие вопросы по тегам