我有当前的XML:
<DocumentElement>
<Customer>
<CustomerId>2315</CustomerId>
<Date>2011-04-28 14:14:00</Date>
<VersionNumber>1</VersionNumber>
<GUID>2E05DE20-02A0-425D-944D-65E5E744FF8A</GUID>
</Customer>
<Customer>
<CustomerId>2316</CustomerId>
<Date>2011-04-28 15:03:00</Date>
<VersionNumber>2</VersionNumber>
<GUID>2E05DE20-02A0-425D-944D-65E5E744FF8A</GUID>
</Customer>
<Customer>
<CustomerId>2317</CustomerId>
<Date>2011-04-28 15:03:00</Date>
<VersionNumber>1</VersionNumber>
<GUID>9995DE20-02A0-425D-944D-65E5E744FF8A</GUID>
</Customer>
</DocumentElement>
我要做的是过滤掉每个GUID中具有最高版本号的一个元素,即将上面的文档转换为:
<DocumentElement>
<Customer>
<CustomerId>2316</CustomerId>
<Date>2011-04-28 15:03:00</Date>
<VersionNumber>2</VersionNumber>
<GUID>2E05DE20-02A0-425D-944D-65E5E744FF8A</GUID>
</Customer>
<Customer>
<CustomerId>2317</CustomerId>
<Date>2011-04-28 15:03:00</Date>
<VersionNumber>1</VersionNumber>
<GUID>9995DE20-02A0-425D-944D-65E5E744FF8A</GUID>
</Customer>
</DocumentElement>
任何能指出正确方向的人都会从哪里开始?
提前致谢。
答案 0 :(得分:2)
作为练习,我尝试使用XSLT 2.0和XPath 2.0来解决这个问题:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no" />
<xsl:template match="/DocumentElement">
<xsl:copy>
<xsl:for-each-group select="Customer" group-by="GUID">
<xsl:copy-of select="current-group()
[VersionNumber=max(current-group()/VersionNumber)]" />
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
主要差异:
使用XSLT 2.0,您无需像this other answer中那样定义xsl:key
,但可以使用xsl:for-each-group ... group-by="GUID"
使用XPath 2.0,您拥有fn:max(...)
功能
答案 1 :(得分:1)
我首先在GUID上声明key,这样可以轻松处理不同的GUID;然后,根据GUID,在其VersionNumber上对相应的Customer元素进行排序,然后只复制第一个(xslt-1.0):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="byGUID" match="Customer" use="GUID"/>
<xsl:template match="/*">
<xsl:copy>
<!-- process first Customer for each distinct GUID -->
<xsl:apply-templates select="//Customer[generate-id()=generate-id(key('byGUID',GUID))]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<!-- sort and process all Customers with the same GUID -->
<xsl:apply-templates select="key('byGUID',GUID)" mode="copyFirst">
<xsl:sort select="VersionNumber" order="descending"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="*" mode="copyFirst">
<!-- only copy the first (highest VersionNumber) -->
<xsl:if test="position()=1">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
使用此节点集交集是处理每个不同GUID的第一个Customer的另一种方法:
<xsl:apply-templates select="//Customer[count(.|key('byGUID',GUID)[1])=1]"/>