Как отсортировать и получить минимальную дату начала (XSLT) - PullRequest
0 голосов
/ 22 марта 2020

Я хочу отсортировать xml и получить минимальную дату начала (удалить другое), используя xslt

Это мой xml

<name>
    <name>
        <firstName>Huio</firstName>
        <lastName>Kuyoshitu</lastName>
        <detail>
            <action>P</action>
            <userId>0902</userId>
            <startDate>2019-01-01T00:00:00.000</startDate>
            <endDate>2030-12-31T00:00:00.000</endDate>
        </detail>
        <detail>
            <action>P</action>
            <userId>0902</userId>
            <startDate>1990-01-01T00:00:00.000</startDate>
            <endDate>1999-12-31T00:00:00.000</endDate>
        </detail>
    </name>
</name>

Я хочу получить подробную информацию, которая имеет минимальная начальная дата (1990-01-01T00: 00: 00.000).

Ожидается xml

<name>
    <name>
        <firstName>Huio</firstName>
        <lastName>Kuyoshitu</lastName>
        <detail>
            <action>P</action>
            <userId>0902</userId>
            <startDate>1990-01-01T00:00:00.000</startDate>
            <endDate>1999-12-31T00:00:00.000</endDate>
        </detail>
    </name>
</name>

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

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

<xsl:template match="/">
    <xsl:copy>
        <xsl:for-each-group select="name/name/detail" group-by="userId">
            <xsl:sort select='startDate' order="ascending" />
            <xsl:for-each select="current-group()">
                <xsl:sort select='startDate' order="ascending" />
                <xsl:if test="position()=1">
                    <xsl:copy-of select="."/>
                </xsl:if>
            </xsl:for-each>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>


</xsl:stylesheet>

, но Метки firstName и lastName исчезают.

Как это https://xsltfiddle.liberty-development.net/93dFepA

1 Ответ

2 голосов
/ 22 марта 2020

XSLT 2 и более поздние версии с функцией XPath 2 min для последовательностей xs:dateTime уменьшают задачу до

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

<xsl:mode on-no-match="shallow-copy"/>

<xsl:template match="name/name">
    <xsl:copy>
        <xsl:apply-templates 
          select="let $min-date := min(detail/startDate/xs:dateTime(.))
                  return node()[not(self::detail) or self::detail[xs:dateTime(startDate) = $min-date]]"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/93dFepA/1

...