我的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>
我需要做什么:
如果存在具有相同doc_id
的行,则我需要仅选择具有较大doc_version
个数字的节点。
预期产出:
<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>
可能会有所帮助:msg_id
是唯一的,因此对于同一msg_id
,doc_id
更大的行会占据最后一个doc_version
。
答案 0 :(得分:1)
与其他一些答案不同,此转换有效:
<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>
应用于提供的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>
产生了想要的正确结果:
<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 Grouping 方法查找属于每个不同群组的一个项目。
正确使用 sorting 查找小组中的最大项目。
正确使用 key()
功能 - 选择给定群组中的所有项目。
答案 1 :(得分:0)
XSLT 1.0解决方案
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:key name="doc_id" match="RowSet/Row" use="doc_id"/>
<xsl:template match="/">
<xsl:for-each select="RowSet/Row[generate-id() = generate-id(key('doc_id',doc_id))]">
<xsl:sort select="doc_id" data-type="number" order="ascending"/>
<xsl:for-each select="../Row[doc_id = current()/doc_id]">
<xsl:sort select="doc_version" data-type="number" order="descending"/>
<xsl:if test="position() = 1">
// stuff
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
逻辑是:
答案 2 :(得分:-1)
试试这个
<xsl:for-each-group select="RowSet/RowSet" group-by="doc_id">
<xsl:for-each select="current-group()">
<xsl:sort select="doc_version" order="desending"/>
<xsl:if test="position()=1">
// do it your stuff here
</xsl:if>
</xsl:for-each>
</xsl:for-each-group>