2010-05-26 4 views
14

Я нашел много примеров, которые ссылаются на Java и C для этого, но как я могу проверить или проверить наличие внешнего файла с XSL.Как проверить наличие внешнего файла с 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

+0

Хороший вопрос (+1). Короткий ответ: в настоящее время невозможно выполнить чистый XSLT 2.0. Длинный ответ и объяснение: см. Мой ответ. :) –

+0

Похоже, что это будет возможно с расширениями EXPath - пакет файлов (http://expath.org/spec/file) ... – potame

ответ

9

Нет, это невозможно сделать с использованием XSLT 2.0/XPath 2.0.

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

Отspec: «The неанализируемого-текстовых доступны функции

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

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

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

Примечания:

Это требует, чтобы функция неанализируемого-текст доступен фактически должна попытаться прочитать ресурс, определенный с помощью URI, и убедитесь, что он правильно закодирован и не содержит никаких символов, которые являются недопустимыми в XML "

конца цитаты.

2

EDIT: Используйте unparsed-text-available function. Это часть xslt 2.0, но не XQuery или автономный XPath.

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

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

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

+0

См. Мой ответ для объяснения, почему это невозможно. –

2

Предлагаемой File Module EXPath specification будет поддерживать файловую систему таких функций, как это (file:exists() в спецификации) в качестве стандартных функций расширения XPath. Существуют еще не XS LT для этого, но его стоит посмотреть.

0

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

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

10

Для кого-то, кто может наткнуться на этот старый вопрос, по кусочкам вместе информацию из различных источников в Интернете, я пришел с этой функцией 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 — не протестировали его с любыми другими процессорами XSLT.

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

<xsl:if test="doc-available('hello_world.xml')"> 
    <!-- ... --> 
</xsl:if> 
+0

С PE9.4, я получаю сообщение об ошибке 'Ошибка в xsl: последовательность в строке 32 столбец 66 файла propertize-opf.xslt: XPST0017 Ошибка синтаксиса XPath на char 12 в строке 32 рядом с {... xists (файл: новый ($ absolute-ur ...}: Невозможно найти подходящую 1-аргументную функцию с именем {java.io.File} new(). Для диагностики при вызовах методов Java используйте параметр командной строки -TJ или задайте конфигурацию свойство FeatureKeys.TRACE_EXTERNAL_FUNCTIONS' – 2013-02-17 17:37:08

+0

@torazaburo: Вы уверены, что передаете 'base-uri()' в качестве второго аргумента в 'java: file-exists()'? Как в: ''. Также обратите внимание, что эта функция будет работать только на XSLT2.0. –

0

Если вам нужно для проверки существования файла 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()"/> 

Ссылки

1

В случае, если кому-то это понадобится и использует fop, я хотел бы поделиться this answer, поскольку он работал для меня как шарм.

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

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

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

0

Назад к уведомлению pgfearo в.

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

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

file:exists($path as xs:string) 

сейчас работает отлично.

Смежные вопросы