Сортировать и получить первую запись в XSLT - PullRequest
0 голосов
/ 29 января 2020

Я хочу отсортировать XML и получить первую запись после сортировки.

У меня есть XML как показано ниже

 <book>
    <book>
        <auther>bell</auther>
        <lastModifiedDateTime>2019-07-22T09:51:48.000</lastModifiedDateTime>
        <code>999</code>
        <date>2019-07-30T00:00:00.000</date>
    </book>
    <book>
        <auther>bell</auther>
        <lastModifiedDateTime>2019-01-01T09:51:48.000</lastModifiedDateTime>
        <code>112</code>
        <date>2020-01-30T00:00:00.000</date>
    </book>
    <book>
        <auther>apple</auther>
        <lastModifiedDateTime>2019-02-02T10:09:40.000</lastModifiedDateTime>
        <code>112</code>
        <date>2018-07-10T00:00:00.000</date>
    </book>
    <book>
        <auther>google</auther>
        <lastModifiedDateTime>2020-01-29T09:51:48.000</lastModifiedDateTime>
        <code>999</code>
        <date>2019-07-30T00:00:00.000</date>
    </book>
</book>

Я хочу отсортировать xml путем сортировки кода по возрастанию , возрастающая дата и получение последней записи (наибольший lastModifiedDateTime), если есть одинаковые «Код» и «Дата»

Это мой ожидаемый результат

   <book>
        <book>
            <auther>apple</auther>
            <lastModifiedDateTime>2019-02-02T10:09:40.000</lastModifiedDateTime>
            <code>112</code>
            <date>2018-07-10T00:00:00.000</date>
        </book>
        <book>
            <auther>bell</auther>
            <lastModifiedDateTime>2019-01-01T09:51:48.000</lastModifiedDateTime>
            <code>112</code>
            <date>2020-01-30T00:00:00.000</date>
        </book>
        <book>
            <auther>google</auther>
            <lastModifiedDateTime>2020-01-29T09:51:48.000</lastModifiedDateTime>
            <code>999</code>
            <date>2019-07-30T00:00:00.000</date>
        </book>
    </book>

Я пробовал этот код

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes" />
    <xsl:template match="book">
        <xsl:copy>
            <xsl:for-each select = "book">
                <xsl:sort select='code' order="ascending"  data-type="number"/>
                <xsl:sort select='date' order="ascending" />
                <xsl:sort select='lastModifiedDateTime' order="descending" />
                <xsl:if test="position()=1">
                    <xsl:copy-of select="."/>
                </xsl:if>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

но я могу получить только одну запись.

это фактическая запись.

<book>
   <book>
       <auther>apple</auther>
       <lastModifiedDateTime>2019-02-02T10:09:40.000</lastModifiedDateTime>
        <code>112</code>
        <date>2018-07-10T00:00:00.000</date>
    </book>
</book> 

1 Ответ

1 голос
/ 29 января 2020

Если я правильно понимаю (большой ЕСЛИ!), Вы хотите сгруппировать записей по code и date и получить последнюю измененную запись в каждой группе, Что может быть достигнуто с помощью:

XSLT 2.0

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

<xsl:template match="/book">
    <xsl:copy>
        <xsl:for-each-group select="book" group-by="string-join((code, date), '|')">
            <xsl:for-each select="current-group()">
                <xsl:sort select='lastModifiedDateTime' order="descending" />
                <xsl:if test="position()=1">
                    <xsl:copy-of select="."/>
                </xsl:if>
            </xsl:for-each>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Если вы хотите, чтобы результаты сортировались по code и date, то сортируйте группы:

<xsl:template match="/book">
    <xsl:copy>
        <xsl:for-each-group select="book" group-by="string-join((code, date), '|')">
            <xsl:sort select='code' order="ascending"  data-type="number"/>
            <xsl:sort select='date' order="ascending" />
            <xsl:for-each select="current-group()">
                <xsl:sort select='lastModifiedDateTime' order="descending" />
                <xsl:if test="position()=1">
                    <xsl:copy-of select="."/>
                </xsl:if>
            </xsl:for-each>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

Демо: https://xsltfiddle.liberty-development.net/ncnu9B9

...