gpt4 book ai didi

XSLT - 按属性分组和排序

转载 作者:行者123 更新时间:2023-12-04 06:11:32 25 4
gpt4 key购买 nike

我有一个包含不同日期价格的 xml

<tour id="12314">
<available date="2012-04-19" price="533" />
<available date="2012-05-09" price="670" />
<available date="2012-05-25" price="600" />
<available date="2012-06-05" price="710" />
<available date="2012-06-08" price="710" />
<available date="2012-06-15" price="710" />
<available date="2012-06-20" price="705" />
</tour>

我的要求是使用 XSLT 获取每个月价格最便宜的节点
例如:所需的输出是:
 <available dt="2012-04-19" price="533" /> 
<available dt="2012-05-25" price="600" />
<available dt="2012-06-20" price="705" />

我首先按如下方式对可用节点进行排序,但我不确定如何以最便宜的价格按月对节点进行分组
<xsl:for-each select="tour[@id='12314']/available">
<xsl:sort select="substring(@dt,1,7)"/>
<xsl:sort select="@price"/>
<!-- I would like to access the available node which has the cheapest price for each month -->
</xsl:for-each>

任何帮助都感激不尽

最佳答案

我提供了总共三种替代解决方案 每个简短而简单(没有嵌套 <xsl:for-each> 和没有排序)。如果可能,我建议使用 XSLT 2.0 解决方案。

一、两种可选的 XSLT 1.0 解决方案:

1. 无 key :

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

<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>

<xsl:template match="available">
<xsl:if test=
"not(@price
>
( preceding-sibling::available
|
following-sibling::available
)
[substring(@date, 1, 7)
=
substring(current()/@date, 1, 7)
]
/@price
)">
<xsl:call-template name="identity"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

2.使用 key :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="kDateByMonth" match="available"
use="substring(@date, 1, 7)"/>

<xsl:template match=
"available
[generate-id()
=
generate-id(key('kDateByMonth',
substring(@date, 1, 7)
)[1]
)
]
">
<xsl:variable name="vsameMonth" select=
"key('kDateByMonth',
substring(@date, 1, 7)
)
"/>

<xsl:copy-of select=
"$vsameMonth[not(@price > $vsameMonth/@price)][1]
"/>
</xsl:template>
</xsl:stylesheet>

当上述两种转换中的任何一种应用于提供的 XML 文档时 :









产生了想要的、正确的结果 :
<tour id="12314">
<available date="2012-04-19" price="533"/>
<available date="2012-05-25" price="600"/>
<available date="2012-06-20" price="705"/>
</tour>

备注 :在这个问题中,没有指定如果一个月内有多个旅行具有相同的最低价格,输出什么。第一个转换将输出所有此类旅行(并且可能会为读者提供选择),而第二个转换每月仅输出一个此类旅行。可以修改这两个转换以实现其他行为。

二、 XSLT 2.0 解决方案 :
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>

<xsl:template match="/*">
<xsl:for-each-group select="*"
group-by="substring(@date, 1,7)">
<xsl:copy-of select=
"current-group()
[@price
=
min(current-group()/@price/number())
]
[1]"/>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>

关于XSLT - 按属性分组和排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7719407/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com