我有这样的XML:
<?xml version="1.0" encoding="UTF-8"?>
<Returns>
<Row>
<Application>
app1
</Application>
<Component>
comp1
</Component>
<Version>
1
</Version>
</Row>
<Row>
<Application>
app1
</Application>
<Component>
comp2
</Component>
<Version>
1
</Version>
</Row>
<Row>
<Application>
app1
</Application>
<Component>
comp1
</Component>
<Version>
2
</Version>
</Row>
<Row>
<Application>
app1
</Application>
<Component>
comp2
</Component>
<Version>
2
</Version>
</Row>
<Row>
<Application>
app2
</Application>
<Component>
comp1
</Component>
<Version>
1
</Version>
</Row>
<Row>
<Application>
app2
</Application>
<Component>
comp2
</Component>
<Version>
1
</Version>
</Row>
<Row>
<Application>
app2
</Application>
<Component>
comp1
</Component>
<Version>
2
</Version>
</Row>
<Row>
<Application>
app2
</Application>
<Component>
comp2
</Component>
<Version>
2
</Version>
</Row>
</Returns>
我需要把它变成这样的东西:
<?xml version="1.0" encoding="UTF-8"?>
<Components>
<Component application="app1" version="2" name="comp1"/>
<Component application="app1" version="2" name="comp2"/>
<Component application="app2" version="2" name="comp1"/>
<Component application="app2" version="2" name="comp2"/>
</Components>
目标是仅显示属于每个应用程序的最新版本的组件。
我写了这个使用muenchian分组的XSL模板:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:key name="application" match="Row" use="Application" />
<xsl:template match="Returns">
<Components>
<xsl:apply-templates select="Row[generate-id(.)=generate-id(key('application',Application)[1])]">
</xsl:apply-templates>
</Components>
</xsl:template>
<xsl:template match="Row">
<xsl:for-each select="key('application', Application)">
<xsl:sort select="Version" order="descending"/>
<xsl:for-each select="Version">
<Component application="{normalize-space(../Application)}" version="{normalize-space(current())}" name="{normalize-space(../Component)}"></Component>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
现在我得到了这个输出:
<?xml version="1.0" encoding="UTF-8"?>
<Components>
<Component application="app1" version="2" name="comp1"/>
<Component application="app1" version="2" name="comp2"/>
<Component application="app1" version="1" name="comp1"/>
<Component application="app1" version="1" name="comp2"/>
<Component application="app2" version="2" name="comp1"/>
<Component application="app2" version="2" name="comp2"/>
<Component application="app2" version="1" name="comp1"/>
<Component application="app2" version="1" name="comp2"/>
</Components>
如何过滤组件以仅获取属于同一应用程序的最新版本的组件?
答案 0 :(得分:0)
在与行匹配的模板中(对于每个不同的“应用程序”),您可能需要添加一个变量,其中包含当前组的最新版本的值。 XSLT 1.0中没有“max”功能,所以你必须这样做
<xsl:variable name="Version">
<xsl:for-each select="key('application', Application)">
<xsl:sort select="Version" order="descending"/>
<xsl:if test="position() = 1">
<xsl:value-of select="Version" />
</xsl:if>
</xsl:for-each>
</xsl:variable>
然后你可以使用最新版本获取当前组中的元素
<xsl:for-each select="key('application', Application)[Version=$Version]">
试试这个XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:key name="application" match="Row" use="Application" />
<xsl:template match="Returns">
<Components>
<xsl:apply-templates select="Row[generate-id(.)=generate-id(key('application',Application)[1])]">
</xsl:apply-templates>
</Components>
</xsl:template>
<xsl:template match="Row">
<xsl:variable name="Version">
<xsl:for-each select="key('application', Application)">
<xsl:sort select="Version" order="descending"/>
<xsl:if test="position() = 1">
<xsl:value-of select="Version" />
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:for-each select="key('application', Application)[Version=$Version]">
<Component application="{normalize-space(Application)}" version="{normalize-space(Version)}" name="{normalize-space(Component)}"></Component>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
这会产生以下输出
<Components>
<Component application="app1" version="2" name="comp1"/>
<Component application="app1" version="2" name="comp2"/>
<Component application="app2" version="2" name="comp1"/>
<Component application="app2" version="2" name="comp2"/>
</Components>