更新时间:2023-11-10 10:24:28
与其他答案不同,
> < xsl:stylesheet version =1.0xmlns:xsl =http://www.w3.org/1999/XSL/变换>
< xsl:output omit-xml-declaration =yesindent =yes/>
< xsl:strip-space elements =*/>
< xsl:key name =kRowByDocIdmatch =Rowuse =doc_id/>
< xsl:template match =/ *>
Row [generate-id()= generate-id(key('kRowByDocId',doc_id)[1])]/>
< / xsl:template>
< xsl:template match =Row>
< xsl:for-each select =key('kRowByDocId',doc_id)>
< xsl:sort select =doc_versiondata-type =numberorder =descending/>
< xsl:if test =position()= 1>< xsl:copy-of select =。/>< / xsl:if>
< / xsl:for-each>
< / xsl:template>
< / xsl:stylesheet>
当应用于提供的XML文档时:
< RowSet>
< Row>
< msg_id> 1< / msg_id>
< doc_id> 1< / doc_id>
< doc_version> 1< / doc_version>
< / Row>
< Row>
< msg_id> 2< / msg_id>
< doc_id> 1< / doc_id>
< doc_version> 2< / doc_version>
< / Row>
< Row>
< msg_id> 3< / msg_id>
< doc_id> 1< / doc_id>
< doc_version> 3< / doc_version>
< / Row>
< Row>
< msg_id> 4< / msg_id>
< doc_id> 2< / doc_id>
< doc_version> 1< / doc_version>
< / Row>
< / RowSet>
想要的,正确的结果会产生:
$ b
< Row>
< msg_id> 3< / msg_id>
< doc_id> 1< / doc_id>
< doc_version> 3< / doc_version>
< / Row>
< Row>
< msg_id> 4< / msg_id>
< doc_id> 2< / doc_id>
< doc_version> 1< / doc_version>
< / Row>
解释:
正确使用 Muenchian分组方法来找到属于每个不同组的一个项目。
正确使用 key()
函数 - 用于选择给定组中的所有项目。
My xml is:
<RowSet>
<Row>
<msg_id>1</msg_id>
<doc_id>1</doc_id>
<doc_version>1</doc_version>
</Row>
<Row>
<msg_id>2</msg_id>
<doc_id>1</doc_id>
<doc_version>2</doc_version>
</Row>
<Row>
<msg_id>3</msg_id>
<doc_id>1</doc_id>
<doc_version>3</doc_version>
</Row>
<Row>
<msg_id>4</msg_id>
<doc_id>2</doc_id>
<doc_version>1</doc_version>
</Row>
<RowSet>
What I need to do:
If there are Rows with the same doc_id
, I need to select only node with the bigger doc_version
number.
Expected output:
<RowSet>
<Row>
<msg_id>3</msg_id>
<doc_id>1</doc_id>
<doc_version>3</doc_version>
</Row>
<Row>
<msg_id>4</msg_id>
<doc_id>2</doc_id>
<doc_version>1</doc_version>
</Row>
<RowSet>
May be it might be helpful: msg_id
is unique, so Row with bigger msg_id
for the same doc_id
hold the last doc_version
.
This transformation works, unlike some other answers:
<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="kRowByDocId" match="Row" use="doc_id"/>
<xsl:template match="/*">
<xsl:apply-templates select=
"Row[generate-id()=generate-id(key('kRowByDocId', doc_id)[1])]"/>
</xsl:template>
<xsl:template match="Row">
<xsl:for-each select="key('kRowByDocId',doc_id)">
<xsl:sort select="doc_version" data-type="number" order="descending"/>
<xsl:if test="position() = 1"><xsl:copy-of select="."/></xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
When applied on the provided XML document:
<RowSet>
<Row>
<msg_id>1</msg_id>
<doc_id>1</doc_id>
<doc_version>1</doc_version>
</Row>
<Row>
<msg_id>2</msg_id>
<doc_id>1</doc_id>
<doc_version>2</doc_version>
</Row>
<Row>
<msg_id>3</msg_id>
<doc_id>1</doc_id>
<doc_version>3</doc_version>
</Row>
<Row>
<msg_id>4</msg_id>
<doc_id>2</doc_id>
<doc_version>1</doc_version>
</Row>
</RowSet>
the wanted, correct result is produced:
<Row>
<msg_id>3</msg_id>
<doc_id>1</doc_id>
<doc_version>3</doc_version>
</Row>
<Row>
<msg_id>4</msg_id>
<doc_id>2</doc_id>
<doc_version>1</doc_version>
</Row>
Explanation:
Proper use of the Muenchian Grouping method for finding one item belonging to each different group.
Proper use of sorting for finding a maximum item in a group.
Proper use of the key()
function -- for selecting all items in a given group.