Search code examples
xsltxsl-foapache-fop

Insert image on first occurence


I have a xml document which looks something like this:

<chapter>
    <para>Just a random text<cross-ref refid="1234">Abb. 1.0</cross-ref>Some more text</para>
    <section-title>Title</section-title>
    <para>and more text text ext<cross-ref refif="1234">Abb 1.0</cross-ref>more more more</para>
</chapter>

As you can see there are two cross-ref elements inside paragraphs. They can occur basically everywhere and are somewhat identified by their refid(but not uniquely). What i am currently trying to do is inserting an image (based on the refid) at the position of the first occurence while keeping the text as a caption. Every other occurence (which are not the first) should just be inline texts containing an internal basic-link to that inserted image. My current solution is:

  <xsl:template match="cross-ref">
    <xsl:choose>
      <xsl:when test="position() = 1">
        <fo:block text-align="center" id="{@refid}">
          <xsl:variable name="refVar" select="@refid"/>
          <xsl:variable name="imageName" select="/chapter/floats/figure[@id=$refVar]/link/@locator" />
          <fo:external-graphic src="url({concat($imageName, '.jpg')})" />
          <fo:block text-align="center" xsl:use-attribute-sets="lit-para">
            <xsl:value-of select="current()" />
          </fo:block>
        </fo:block>
      </xsl:when>

      <xsl:otherwise>
        <fo:basic-link internal-destination="{@refid}">
          <xsl:value-of select="current()" />
        </fo:basic-link>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

It does work on some cases, but since position() is not always 1 some images are not getting inserted correctly. What are my options? Thank you!

EDIT: I should clarify. The image should get inserted at the first occurence of a "new" refid. Thus. Each refid only has one image and every other cross-refelement with the same refid points to that image


Solution

  • You have to change the test in your xsl:when, so that it is true only for the first occurrence of each @ref-id value; in other words, you have to check that no preceding cross-ref element has the same @ref-id:

    <xsl:when test="not(preceding::cross-ref[@ref-id = current()/@ref_id])">
    ...