简体   繁体   中英

XSL - Exclude some elements with position()

In my XML file, i have a list of external references like these

 <references>
     <reference id="ref1" ref-author="a"/>
     <reference id="ref2" ref-author="m"/>
     <reference id="ref3" ref-author="c"/>
  </references>

In this document, I have an element citations to associate to the wanted reference.

<cita ref="ref3"/>

The problem is, I only want it to transform the references that are referenced in the document. I want to number each reference, ordered by the author. I've tried to use position() for this but, if some reference is not transformed, it will "count" anyway. So, if my second reference is missing, the others are displayed as [1] [3], instead of [1] [2] as expected.

This is my XSL for references:

<xsl:template match="references">
    <div class="references">
        <h2>References</h2>
        <xsl:apply-templates select="reference">
            <xsl:sort select="@ref-author"/>
        </xsl:apply-templates>      
    </div>
</xsl:template>

<xsl:key use="@ref" name="listed-references" match="cita"></xsl:key>
<xsl:template match="reference">
    <xsl:choose>
        <xsl:when test="key('listed-references', @id)">
            <p>
                <xsl:attribute name="id"><xsl:value-of select="@id"></xsl:value-of></xsl:attribute>
                [<xsl:number value="position()"/>] <xsl:value-of select="@ref-author"/>, 
            </p>
        </xsl:when>
    </xsl:choose>
</xsl:template> 

Is there any way to restrict the position() only to count the elements "reference" that will be transformed? Or there is another workaround?

Thanks.

Try modifying your xsl:apply-templates . This will change the current node list which will allow position() to give you an accurate result.

Example...

XML Input

<doc>
    <references>
        <reference id="ref1" ref-author="a"/>
        <reference id="ref2" ref-author="m"/>
        <reference id="ref3" ref-author="c"/>
    </references>
    <cita ref="ref3"/>
    <cita ref="ref2"/>
</doc>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="references">
        <div class="references">
            <h2>References</h2>
            <xsl:apply-templates select="reference[key('listed-references', @id)]">
                <xsl:sort select="@ref-author"/>
            </xsl:apply-templates>      
        </div>
    </xsl:template>

    <xsl:key use="@ref" name="listed-references" match="cita"/>

    <xsl:template match="reference">
        <p id="{@id}">
            <xsl:value-of select="concat('[',position(),'] ',@ref-author)"/>
            <xsl:if test="not(position()=last())">,</xsl:if>
        </p>
    </xsl:template>

</xsl:stylesheet>

Output

<div class="references">
   <h2>References</h2>
   <p id="ref3">[1] c,</p>
   <p id="ref2">[2] m</p>
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM