xsl: сортировка файла XML с использованием нескольких элементов

Я пытаюсь отсортировать кучу записей в файле XML. Хитрость в том, что мне нужно сортировать, используя разные элементы для разных узлов. Чтобы дать самый простой пример, Ключом сортировки является фамилия, если она присутствует, в противном случае это псевдоним, если он присутствует, и имя в противном случае.

У меня возникли трудности, поскольку использование переменных в качестве ключей xsl: sort , по-видимому, недопустимо .

Мой лучший лучший вариант - это двухэтапное преобразование: добавить специальный тег в каждая запись с использованием этой таблицы стилей








    
    
     
        
        
        
        
             
            
            
                
                      
                      
                
            
        
    
  


И затем сортировка полученного XML





    
        
    



   
   
   


Хотя это двухступенчатое преобразование работает, мне интересно, есть ли более элегантный способ сделать это за один раз?

7
задан Community 23 May 2017 в 12:08
поделиться

2 ответа

Вы можете использовать функцию XPath concat:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:template match="/buddies">
        <xsl:apply-templates>
            <xsl:sort select="concat(last,nick,first)"/>
        </xsl:apply-templates>
    </xsl:template>
    <xsl:template match="person">
        <xsl:value-of select="concat(normalize-space(concat(first,
                                                            ' ',
                                                            nick,
                                                            ' ',
                                                            last)),
                                     '&#xA;')"/>
    </xsl:template>
</xsl:stylesheet>
5
ответ дан 7 December 2019 в 09:55
поделиться

Можете ли вы попробовать, если этот шаблон дает ожидаемый результат? Для вашего простого примера он дает правильный ответ, но могут быть угловые случаи, которые не будут работать. Normalize-space используется здесь для удаления начальных и конечных пробелов, если один из элементов отсутствует.

<xsl:template match="/buddies">
    <xsl:for-each select="person">
        <xsl:sort select="normalize-space(concat(last, ' ', nick, ' ', first))"/>

        <xsl:if test="first">
            <xsl:value-of select="first" />
            <xsl:text> </xsl:text>
        </xsl:if>

        <xsl:if test="nick">
            <xsl:value-of select="nick" />
            <xsl:text> </xsl:text>
        </xsl:if>

        <xsl:value-of select="last" />
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>
1
ответ дан 7 December 2019 в 09:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: