XML - сортировка на основе перевернутых слов предложения с XSLT 1.0 - PullRequest
0 голосов
/ 23 марта 2020

У меня есть xml файл, подобный этому:

<?xml version="1.0" encoding="utf-8"?>
<students>
  <student>
    <name>Clark Johnson</name>
  </student>
  <student>
    <name>John Doe</name>
  </student>
  <student>
    <name>Andy Ng</name>
  </student>
</students>

Я уже знаю, что если я использую xsl:sort, он выдаст

Andy Ng
Clark Johnson
John Doe

Однако я хочу его сортировать, основываясь на перевернутых словах (Кларк Джонсон - Джонсон Кларк, Джон Доу - Доу Джон, а Энди Нг - Эндж Энди) и вывести примерно так:

John Doe
Clark Johnson
Andy Ng

Как мне этого добиться с помощью XSLT 1.0 ? У меня уже есть шаблон, который может перевернуть слова, но я не знаю, как реализовать его в сортировке. Вот шаблон:

<xsl:template name="reverse">
    <xsl:param name="text"/>
    <xsl:if test="contains($text, ' ')">
      <xsl:call-template name="reverse">
        <xsl:with-param name="text" select="substring-after($text, ' ')"/>
      </xsl:call-template>
      <xsl:text> </xsl:text>
    </xsl:if>
    <xsl:value-of select="substring-before(concat($text, ' '), ' ')"/>
  </xsl:template>

1 Ответ

0 голосов
/ 23 марта 2020

Вот один из способов посмотреть на это:

XSLt 1.0 (+ функция набора узлов EXSLT)

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="text"/>

<xsl:template match="/students">
    <!-- pre-process -->
    <xsl:variable name="students">
        <xsl:for-each select="student">
            <student name="{name}">
                <xsl:call-template name="reverse">
                    <xsl:with-param name="text" select="name"/>
                </xsl:call-template>
            </student>  
        </xsl:for-each>
    </xsl:variable>
    <!-- output -->
    <xsl:for-each select="exsl:node-set($students)/student">
        <xsl:sort/>
        <xsl:value-of select="@name"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

<xsl:template name="reverse">
    <xsl:param name="text"/>
    <xsl:if test="contains($text, ' ')">
      <xsl:call-template name="reverse">
        <xsl:with-param name="text" select="substring-after($text, ' ')"/>
      </xsl:call-template>
      <xsl:text> </xsl:text>
    </xsl:if>
    <xsl:value-of select="substring-before(concat($text, ' '), ' ')"/>
  </xsl:template>

</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...