【问题标题】:xslt to keep most recent entries grouped by keyxslt 将最近的条目按键分组
【发布时间】:2021-08-26 06:48:17
【问题描述】:

我需要保留输入 xml 中按键值分组的最新条目。可以用 xsl 2.0 做到这一点吗? 输入

<root>
<line>
    <date>2021-01-01T00:00:00</date>
    <field1>AAA</field1>
    <field2>1</field2>
</line>
<line>
    <date>2021-01-01T23:00:00</date>
    <field1>BBB</field1>
    <field2>1</field2>
</line>
<line>
    <date>2021-01-02T00:00:00</date>
    <field1>CCC</field1>
    <field2>2</field2>
</line>
输出应该是
<root>
<line>
    <date>2021-01-01T23:00:00</date>
    <field1>BBB</field1>
    <field2>1</field2>
</line>
<line>
    <date>2021-01-02T00:00:00</date>
    <field1>CCC</field1>
    <field2>2</field2>
</line>
xsl 保留按 field2 分组的最新条目,因此结果是两个条目(field2= 1 和 field2=2)。
<?xml version="1.0" encoding="UTF-8"?>

<xsl:template match="/">
    <xsl:for-each-group select="root/line" group-by="field2">
        <xsl:sort select="date"/>
        <line>
            <xsl:copy-of select="node()"/>
        </line>
    </xsl:for-each-group>
</xsl:template>

样式表>

【问题讨论】:

  • 是的,这是可能的。你到底在哪里坚持这个?
  • XSLT 2 和 3 分组显示在 stackoverflow.com/tags/xslt-grouping/info 中,排序是通过处理 current-group() 并使用 xsl:sort 完成的,或者您可以只选择 current-group() 中的项目和 @987654329 @.
  • 我已经使用了问题中更新的 xsl 但无法正常工作。
  • “不工作”不能很好地描述问题。实际结果是什么?您的 XSLT 处理器是否支持 XSLT 2.0?您的样式表声明 version="1.0"
  • 它保留 2 行,但 field1=AAA 而不是 BBB。

标签: date xslt group-by


【解决方案1】:

您的尝试对进行排序,而不是每个组中的行。然后它复制每个组中的第一个节点。

要通过排序来做到这一点,您需要执行以下操作:

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="/root">
    <xsl:copy>
        <xsl:for-each-group select="line" group-by="field2">
            <xsl:variable name="sorted-group">
                <xsl:perform-sort select="current-group()">
                    <xsl:sort select="date" order="descending"/>
                </xsl:perform-sort>            
            </xsl:variable>
            <xsl:copy-of select="$sorted-group/line[1]"/>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

请注意,这只会按日期降序复制 first 行。如果有两行日期相同,则仅将其中的第一行(按文档顺序)复制到输出中。


或者,您可以选择在其组中具有最大 dateTime 的行:

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

<xsl:template match="/root">
    <xsl:copy>
        <xsl:for-each-group select="line" group-by="field2">
            <xsl:variable name="max-dateTime" select="max(current-group()/date/xs:dateTime(.))" />
            <xsl:copy-of select="current-group()[date=$max-dateTime]"/>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

这里的平局可以通过复制两行来解决。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-21
    • 1970-01-01
    • 2020-03-22
    • 1970-01-01
    • 2017-03-19
    • 1970-01-01
    相关资源
    最近更新 更多