如何排序和获取最短开始日期 (XSLT)
How to sort and get minimum start date (XSLT)
我想使用 xslt
对 xml 进行排序并获取最短开始日期(删除其他日期)
这是我的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 标签消失了。
XSLT 2 及更高版本在 xs:dateTime
序列上使用 XPath 2 min
函数将任务减少到
<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>
我想使用 xslt
对 xml 进行排序并获取最短开始日期(删除其他日期)这是我的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 标签消失了。
XSLT 2 及更高版本在 xs:dateTime
序列上使用 XPath 2 min
函数将任务减少到
<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>