xsl-list
[Top] [All Lists]

[xsl] How could I detect/prevent a file not found exception in document()?

2019-02-05 07:21:22
Hi

 

A set of templates which are used to fill in the clickable text of a
cross-reference are occasionally failing for me with a "file not found"
exception. The processor we are using for this is Saxon but I'm hoping that
there may be a way to code round the problem that is not processor-specific,
so I am posting the relevant part of it here rather than on the Saxon list.

The stylesheet containing these templates is currently XSL 1.0 because an
extensive array of stylesheets include it, and some of them have to be XSL
1.0. But I could easily do a separate XSL 2.0 version if that helped avoid
this issue.

 

For reasons outside the scope of this query, a lot of our content is
generated dynamically, which means that sometimes content is passed to the
transform where a link may be spurious - typically when this happens an
editor has recorded the link href as e.g. "file1#id1" but by the time the
transform is run id1 is now located in a different document. The stylesheet
copes with this by first looking up the exact file1#id1, but if this returns
an empty string its fallback mechanism is to look for the id in a cached
document which is retained after every build.

 

Thus we have something like this

  <!-- local key for cross references -->

  <xsl:key name="linkidkey" match="*[@id]" use="@id" />

 

  <!-- return the text that should be substituted in a link -->

  <xsl:template name="link-text">

    <xsl:param name="linkurl" />

    <xsl:variable name="linkfile" select="substring-before($linkurl,'#')" />

    <xsl:variable name="linkid" select="substring-after($linkurl,'#')" />

  ...

    <xsl:variable name="simplelink">

      <!-- doc ONE -->

      <xsl:for-each select="document($linkfile,/)">

        <xsl:value-of select="normalize-space(key('linkidkey',$linkid)" />

     </xsl:for-each>

    </xsl:variable>

  ...

    <xsl:choose>

      <!-- can find the file/id -->

      <xsl:when test="$simplelink != ''">

        <xsl:value-of select="$simplelink" />

      </xsl:when>

      <!-- can't find the file/id, so need a bit of magic: use the cache
document from the previous build -->

      <xsl:otherwise>

        <xsl:variable name="cachefile">

          <xsl:call-template name="cache-filename">

            <xsl:with-param name="pathname" select="$linkfile" />

          </xsl:call-template>

        </xsl:variable>

        <xsl:variable name="cachedlink">

          <!-- doc TWO -->

          <xsl:for-each select="document($cachefile,/)">

            <xsl:value-of select="normalize-space(key('linkidkey',$linkid))"
/>

          </xsl:for-each>

        </xsl:variable>

        <xsl:choose>

          <xsl:when test="$cachedlink != ''">

            <xsl:value-of select="$cachedlink" />

          </xsl:when>

          <xsl:otherwise>

            <xsl:value-of select="$linkurl" />

          </xsl:otherwise>

        </xsl:choose>

      </xsl:otherwise>

    </xsl:choose>

  </xsl:template>

 

As it happens, the lookup marked "doc ONE" never gives an error, although it
often fails to find the link target. But the lookup marked "doc TWO" can
fail under some circumstances, which causes the template to fail with a
java.io.FileNotFoundException when it evaluates the document($cachefile,/)
function.

Is there any way to detect this failure before it happens? I'd like to
return "MISSING REFERENCE" owtte as the text of the link rather than (as at
present) have no hyperlink generated at all when this occurs.

 

cheers

T

 

 
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--
<Prev in Thread] Current Thread [Next in Thread>