Как проверить наличие внешнего файла с помощью XSL? - PullRequest
14 голосов
/ 27 мая 2010

Я нашел много примеров, которые ссылаются на Java и C для этого, но как мне проверить или проверить, существует ли внешний файл с помощью XSL.

Во-первых, я понимаю, что это всего лишь фрагмент, но это часть огромной таблицы стилей, поэтому я надеюсь, что этого достаточно, чтобы показать мою проблему.

    <!-- 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"/>

То, что я хотел бы сделать, помещается в выражение «если», за пределами строки {$SMSname}.jpg. То есть:

                     <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>                       

Из-за "группировки" и т. Д. Я использую XSLT 2.0. Я надеюсь, что это то, что можно сделать. Я даже больше надеюсь, что это что-то простое.

Как всегда, заранее спасибо за любую помощь. LO

Ответы [ 9 ]

10 голосов
/ 14 января 2013

Для тех, кто может наткнуться на этот старый вопрос, собрав воедино информацию из различных источников в Интернете, я предложил эту функцию XSLT2, которая использует расширение Java для проверки существования файла:

<?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>

Затем вы можете использовать такую ​​функцию:

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

Это работает по крайней мере с Saxon 9.1.0.5J & mdash; не тестировал его с другими процессорами XSLT.

Примечание : Если файл, чье существование вы проверяете, является файлом XML, и вы используете XSLT2, вы также можете использовать встроенную функцию doc-available():

<xsl:if test="doc-available('hello_world.xml')">
  <!-- ... -->
</xsl:if>
9 голосов
/ 27 мая 2010

Нет, этого нельзя сделать с помощью XSLT 2.0 / XPath 2.0.

Функция XSLT 2.0 unparsed-text-available () подходит только для поиска текстовых файлов, и даже если существует текстовый файл с указанным URI, эта функция может вернуть false ( ), поскольку он также должен прочитать содержимое файла и убедиться, что он содержит только разрешенные символы.

Из spec :

"Функция unparsed-text-available определяет, будет ли вызов функции unparsed-text с одинаковыми аргументами возвращать строку.

Если первый аргумент является пустой последовательностью, функция возвращает false. Если второй аргумент является пустой последовательностью, функция ведет себя так, как если бы второй аргумент был опущен.

В других случаях функция возвращает true, если вызов unparsed-text с теми же аргументами будет успешным, и false, если вызов unparsed-text с теми же аргументами завершится неудачей с невосстановимой динамической ошибкой.

Примечание:

Для этого требуется, чтобы функция unparsed-text-available фактически пыталась прочитать ресурс, указанный в URI, и убедиться, что он правильно закодирован и не содержит символов, которые недопустимы в XML «

Конец цитаты.

2 голосов
/ 02 сентября 2015

Если кому-то еще это нужно и он использует fop, я хотел бы поделиться этим ответом , так как он работал для меня как шарм.

Я нашел решение:

<xsl:when test="fs:exists(fs:new('myfile.html'))" xmlns:fs="java.io.File">
    <!-- do something here... -->
</xsl:when>

и работает независимо от XSLT 1.0 или 2.0

2 голосов
/ 27 мая 2010

Предлагаемая спецификация файлового модуля EXPath будет поддерживать функции файловой системы, такие как эта (file:exists() в спецификации), в качестве стандартных функций расширения XPath. Для этого еще нет реализации XSLT, но ее стоит посмотреть.

2 голосов
/ 27 мая 2010

РЕДАКТИРОВАТЬ: Используйте функция unparsed-text-available . Он является частью xslt 2.0 , но не XQuery или автономной XPath.

Я оставил свой предыдущий ответ здесь, чтобы вы могли следовать по пути неопределенности ...

Я не верю, что в XSLT есть способ сделать это, используя стандартные функции. Вы можете сделать это, используя функции расширения, как описано здесь , для Java.

Существует функция unparsed-text-available , но я не уверен, является ли это стандартной функцией. Есть пример его использования на Zvon . Доступный unparsed-text упоминается здесь как часть xslt 2.0 и поддерживается в Saxon.

1 голос
/ 14 сентября 2017

Вернуться к уведомлению pgfearo.

Предлагаемая спецификация файлового модуля EXPath будет поддерживать файловую систему такие функции, как эта (file: exist () в спецификации) как стандартный XPath функции расширения. Для этого еще нет реализации XSLT, но стоит посмотреть.

Для тех, кому нужно проверить, существует файл или нет.

file:exists($path as xs:string)

теперь отлично работает.

0 голосов
/ 30 января 2019

Если вы все еще хотите сделать это в XSLT, вот решение, я сделал это для себя, как описано ниже.

Это не будет работать с обычным java.io.File классом в XSLT. Поэтому я использовал java.nio.file.Files class.

JARS требуется - servelt.jar w: пространство имен нашего собственного Java-класса, в котором определен метод pathFromURI.

Код:

<xsl:variable name="fileURI" select="u:new($absoluteFilePath)" xmlns:u="java:java.net.URI"/>
<xsl:variable name="filePathFromURI" select="w:pathFromURI($fileURI)"/>
<xsl:variable name="fileNotExist" select="not(files:exists($filePathFromURI, /..)) or files:size($filePathFromURI) = 0"/>

public static java.nio.file.Path pathFromURI(java.net.URI uri) throws Exception {
    return java.nio.file.Paths.get(uri);
}
0 голосов
/ 12 сентября 2013

Если вам нужно проверить наличие XML-файла, используйте внешнюю сущность и встроенный тип документа:

<!DOCTYPE foo [ <!ENTITY bar SYSTEM "baz.xml"> ]>

Затем добавьте объект в таблицу стилей:

&bar;

Процессор отключится, если файл не найден.

Если вы знаете, что файлы существуют, но хотите динамически загрузить один из многих, используйте функцию concat и блок choose/when:

<xsl:variable name="page_name">
<xsl:choose>
  <xsl:when test="$page = 1">
    <xsl:value-of select="'page1.xml'"/>
  </xsl:when>
  <xsl:when test="$page = 2">
    <xsl:value-of select="'page2.xml'"/>
  </xsl:when>
  <!--...-->
  <xsl:when test="$page = 9">
    <xsl:value-of select="'page9.xml'"/>
  </xsl:when>
  <xsl:when test="$page = 10">
    <xsl:value-of select="'page10.xml'"/>
  </xsl:when>
  <xsl:otherwise>
    <xsl:value-of select="'page0.xml'"/>
  </xsl:otherwise>
</xsl:choose>
</xsl:variable>

<xsl:variable name="agree" select="document(concat('include/pages/',$page_name))//processing-instruction()"/>

Ссылки

0 голосов
/ 05 ноября 2011

Это не может быть сделано только стандартным XSLT, вы должны использовать функцию расширения или какой-то раздражающий обходной путь. Существует два метода, использующих функции расширения: использование стандартного java / .NET для пользовательских функций (работает с некоторыми версиями Saxon, AltovaXML и других) или использование функций расширения, специфичных для процессора, таких как saxon: file-last -ified () / саксонской: последнее изменение () . Вы можете найти пример кода здесь , ищите intern: file-exist ().

Если вы не можете использовать функции расширения, вы можете либо сгенерировать внешний файл XML, который содержит информацию о вашей файловой системе и передать его в вашу таблицу стилей, либо вы можете обернуть двоичные изображения в SVG и затем использовать fn: doc-available ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...