Можно ли использовать xsl:script с XMLCompiledTransform?
Я создал XSL-скрипт, который использовал msxml:script для использования с XMLCompiledTransform, но люди, которым это нужно, сказали, что скрипт не будет работать в их среде Linux/Perl (это буквально столько, сколько я знаю о том, как они используют XSL) потому что он "использует специфические расширения Microsoft". Поэтому я пытаюсь сделать XSL более нейтральным, используя xsl: script. Тем не менее, мне трудно заставить его работать.
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:theScript="urn:CustomScript" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="xsl theScript fo xs fn">
<xsl:output method="xml" indent="yes" version="1.0" encoding="utf-8" omit-xml-declaration="no"/>
<xsl:script language="javascript" implements-prefix="theScript">
<![CDATA[
function test() {return "test"; }
]]>
</xsl:script>
<xsl:template match="/">
<test>
<xsl:value-of select="theScript:test()" />
</test>
</xsl:template>
</xsl:stylesheet>
Выше приведено сообщение об ошибке "Не удается найти сценарий или внешний объект, который реализует префикс" urn:CustomScript "".
Если я избавлюсь от xmlns:theScript="urn:CustomScript"
это дает мне ошибку "Префикс 'theScript' не определен".
Я также попытался удалить все следы префикса "theScript" и просто с помощью implements-prefix="local"
но это тоже не работает. Это говорит мне test
неизвестная функция XSLT
Так что я просто делаю что-то не так, или XMLCompiledTransform не поддерживает xsl:script
?
2 ответа
xsl:script
определен только в XSLT1.1, но этот стандарт был отменен в пользу XSLT2.0, поэтому, если вы ищете мобильность, реалистично, я бы не рекомендовал его использовать.
Самая переносимая форма XSLT - это, безусловно, XSLT1.0, поскольку ее поддержка гораздо шире. Хотя некоторые вещи определенно проще в XSLT2.0, вы, вероятно, обнаружите, что большинство скриптовых кодов, которые вы, возможно, захотите сделать, могут быть выполнены только в XSLT. XSLT2.0 может определять функции, но вы можете эмулировать функции, используя именованные шаблоны в XSLT1.0, это просто немного громоздко.
XSLT2.0:
<xsl:template match="/">
<xsl:value-of select="test('param')" />
</xsl:template>
<xsl:function name="test" as="xs:string">
<xsl:param name="param" as="xs:string" />
<xsl:text>Test</xsl:text>
</xsl:function>
XSLT1.0:
<xsl:template match="/">
<xsl:call-template name="test">
<xsl:with-param name="param" select="'param'" />
</xsl:call-template>
</xsl:template>
<xsl:template name="test">
<xsl:param name="param" />
<xsl:text>Test</xsl:text>
</xsl:template>
Однако этот параметр не используется в этом примере, но вы поняли идею.
Здесь нет xsl:script
инструкция в XSLT.
Здесь нет XMLCompiledTransform
класс, который является частью NET.
Существующий XslCompiledTransform
Класс, который поставляется с.NET в пространстве имен System.Xml.Xsl, реализует совместимый процессор XSLT 1.0 - поэтому он не поддерживает никаких инструкций xsl:script
,
Рекомендация. Чтобы добиться истинной переносимости приложения XSLT, не используйте какие-либо (встроенные или нет) функции расширения или недокументированные, необязательные или несовместимые функции.
Хотя ряд процессоров XSLT 1.0 поддерживают EXSLT, XslCompiledTransform
процессор поддерживает только node-set()
Функция расширения EXSLT.