Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I check for the existence of an external file with XSL?

I've found a lot of examples that reference Java and C for this, but how do I, or can I, check for the existence of an external file with XSL.

First, I realize that this is only a snippet, but it's part of a huge stylesheet, so I'm hoping it's enough to show my issue.

    <!-- Use this template for Received SMSs -->
<xsl:template name="ReceivedSMS">
    <!-- Set/Declare "SMSname" variable (local, evaluates per instance) -->
    <xsl:variable name="SMSname">
        <xsl:value-of select=" following-sibling::Name"/>
    </xsl:variable>
    <fo:table font-family="Arial Unicode MS" font-size="8pt" text-align="start">
        <fo:table-column column-width=".75in"/>
        <fo:table-column column-width="6.75in"/>
        <fo:table-body>
            <fo:table-row>
                <!-- Cell contains "speakers" icon -->
                <fo:table-cell display-align="after">
                    <fo:block text-align="start">
                        <fo:external-graphic src="../images/{$SMSname}.jpg" content-height="0.6in"/>

What I'd like to do, is put in an "if" statement, surronding the {$SMSname}.jpg line. That is:

                     <fo:block text-align="start">
                        <xsl:if test="exists( the external file {$SMSname}.jpg)">
                            <fo:external-graphic src="../images/{$SMSname}.jpg" content-height="0.6in"/>                            
                        </xsl:if>
                        <xsl:if test="not(exists( the external file {$SMSname}.jpg))">
                            <fo:external-graphic src="../images/unknown.jpg" content-height="0.6in"/>                            
                        </xsl:if>
                    </fo:block>                       

Because of "grouping", etc., I'm using XSLT 2.0. I hope that this is something that can be done. I hope even more that it's something simple.

As always, thanks in advance for any help. LO

like image 730
LOlliffe Avatar asked May 26 '10 23:05

LOlliffe


People also ask

Which XSL element is used to extract information from XML document?

The XSLT <xsl:value-of> element is used to extract the value of selected node. It puts the value of selected node as per XPath expression, as text.

How many components are available in XSL?

It consists of three parts: XSL Transformations (XSLT) a language for transforming XML; The XML Path Language (XPath)

What is XSL FO file?

XSL-FO (XSL Formatting Objects) is a markup language for XML document formatting that is most often used to generate PDF files. XSL-FO is part of XSL (Extensible Stylesheet Language), a set of W3C technologies designed for the transformation and formatting of XML data.


2 Answers

For anyone else who might stumble upon this old question, by piecing together information from various sources on the internet, I came up with this XSLT2 function that uses a Java extension for checking whether a file exists:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:java="http://www.java.com/"
  exclude-result-prefixes="java xs">

  <xsl:function name="java:file-exists" xmlns:file="java.io.File" as="xs:boolean">
    <xsl:param name="file" as="xs:string"/>
    <xsl:param name="base-uri" as="xs:string"/>

    <xsl:variable name="absolute-uri" select="resolve-uri($file, $base-uri)" as="xs:anyURI"/>
    <xsl:sequence select="file:exists(file:new($absolute-uri))"/>
  </xsl:function>

</xsl:stylesheet>

You can then use the function like this:

<xsl:if test="java:file-exists($filename, base-uri())">
  <!-- ... -->
</xsl:if>

This works at least with Saxon 9.1.0.5J — haven't tested it with any other XSLT processors.

Note: If the file for whose existence you're checking is an XML file and you're using XSLT2, you can also use the built-in doc-available() function:

<xsl:if test="doc-available('hello_world.xml')">
  <!-- ... -->
</xsl:if>
like image 127
Eero Helenius Avatar answered Sep 22 '22 11:09

Eero Helenius


No, this cannot be done using XSLT 2.0/XPath 2.0.

The XSLT 2.0 function unparsed-text-available() is only suitable for locating text files and even if a text file with the specifies URI exists this function may return false(), because it also must read the contents of the file and check that it only contains allowed characters.

From the spec:

"The unparsed-text-available function determines whether a call on the unparsed-text function with identical arguments would return a string.

If the first argument is an empty sequence, the function returns false. If the second argument is an empty sequence, the function behaves as if the second argument were omitted.

In other cases, the function returns true if a call on unparsed-text with the same arguments would succeed, and false if a call on unparsed-text with the same arguments would fail with a non-recoverable dynamic error.

Note:

This requires that the unparsed-text-available function should actually attempt to read the resource identified by the URI, and check that it is correctly encoded and contains no characters that are invalid in XML "

End of quotation.

like image 25
Dimitre Novatchev Avatar answered Sep 20 '22 11:09

Dimitre Novatchev