在XSLT中基于Attribute包装最后一个唯一元素

时间:2016-12-22 08:03:06

标签: xml xslt

如何在XSLT中包装最后的唯一元素

输入:

<main>
    <level1>
        <level2 ID="spa3" type="starpage_print" product-citation-id="Ia9572840aadb11e6aa049569ac37328a" productTypeId="1" pubId="7047" starDesc="Main" shortName="Cal.Rptr.3d" venueId="2055">Cal.Rptr.3d 281</level2>
    </level1>
    <level1>
        <level2 ID="spa4" type="starpage_print" product-citation-id="Ia9572840aadb11e6aa049569ac37328a" productTypeId="1" pubId="7047" starDesc="Main" shortName="Cal.Rptr.3d" venueId="2055">Cal.Rptr.3d 282</level2>
    </level1>
    <level1>
        <level2 ID="spb5" product-citation-id="Ia9572840aadb11e6aa049569ac37328a" productTypeId="1" pubId="7047" starDesc="Main" shortName="Cal.Rptr.3d" venueId="2055" type="starpage_print">Cal.Rptr.3d 283</level2>
    </level1>
    <level1>
        <level2 ID="spb1" product-citation-id="Ia956b310aadb11e6aa049569ac37328a" productTypeId="1" pubId="4645" starDesc="Both" shortName="P.3d" venueId="2055" type="starpage_print">P.3d 1117</level2>
    </level1>
    <level1>
        <level2 ID="spb2" product-citation-id="Ia956b310aadb11e6aa049569ac37328a" productTypeId="1" pubId="4645" starDesc="Both" shortName="P.3d" venueId="2055" type="starpage_print">P.3d 1118</level2>
    </level1>
</main>

我需要找到基于pubId属性的最后一个唯一元素。 在这个例子中有2个不同的pubId的7047和4645。 我需要找到最后一次出现。

预期产出:

 <main>
    <level1>
        <level2 ID="spa3" type="starpage_print" product-citation-id="Ia9572840aadb11e6aa049569ac37328a" productTypeId="1" pubId="7047" starDesc="Main" shortName="Cal.Rptr.3d" venueId="2055">Cal.Rptr.3d 281</level2>
    </level1>
    <level1>
        <level2 ID="spa4" type="starpage_print" product-citation-id="Ia9572840aadb11e6aa049569ac37328a" productTypeId="1" pubId="7047" starDesc="Main" shortName="Cal.Rptr.3d" venueId="2055">Cal.Rptr.3d 282</level2>
    </level1>
        <level3>
    <level1>
        <level2 ID="spb5" product-citation-id="Ia9572840aadb11e6aa049569ac37328a" productTypeId="1" pubId="7047" starDesc="Main" shortName="Cal.Rptr.3d" venueId="2055" type="starpage_print">Cal.Rptr.3d 283</level2>
    </level1>
         </level3>
    <level1>
        <level2 ID="spb1" product-citation-id="Ia956b310aadb11e6aa049569ac37328a" productTypeId="1" pubId="4645" starDesc="Both" shortName="P.3d" venueId="2055" type="starpage_print">P.3d 1117</level2>
    </level1>
         <level3>
    <level1>
    <level2 ID="spb2" product-citation-id="Ia956b310aadb11e6aa049569ac37328a" productTypeId="1" pubId="4645" starDesc="Both" shortName="P.3d" venueId="2055" type="starpage_print">P.3d 1118</level2>
    </level1>
        </level3>
</main>

1 个答案:

答案 0 :(得分:1)

假设XSLT 2.0,您可以识别由键定义的组中的最后一项,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>

    <xsl:key name="group" match="level2" use="@pubId"/>

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

    <xsl:template match="level1[level2[. is key('group', @pubId)[last()]]]">
        <level3>
            <xsl:copy-of select="."/>
        </level3>
    </xsl:template>

</xsl:stylesheet>

使用XSLT 1.0,您可以使用相同的密钥,但需要将最后一个模板写为

<xsl:template match="level1[level2[generate-id() = generate-id(key('group', @pubId)[last()])]]">
    <level3>
        <xsl:copy-of select="."/>
    </level3>
</xsl:template>