Я взломал эту проблему, отладив ее сам, несмотря на отсутствие знаний XSLT.Это решение фокусируется на использовании Xalan (интерпретирующая версия, xalan.jar или, если быть более точным org.apache.xalan.processor.TransformerFactoryImpl
) в качестве предпочтительного процессора Java XSLT.Решение требует внесения изменений в скелет схематора, а также его непереносимость.
После выделения проблемного фрагмента кода XSL из iso_schematron_skeleton_for_xslt1.xsl
я выяснил, что является причиной просто исчезновения пространства имен "http://exslt.org/common""из таблицы стилей, которая должна была быть сгенерирована преобразованием (скелет является мета-таблицей стилей, что означает, что его вывод также является таблицей стилей). И генерирующая, и сгенерированная таблица стилей используют функции из этого пространства имен EXSLT и задают его в двух xsl: элементы таблицы стилей внутри одного файла XSL, кажется, заставляют все Java-процессоры XSLT взрываться. Серьезно. Если вы сделаете это (см. пример ниже), пространство имен в сгенерированной таблице стилей просто исчезнет.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" omit-xml-declaration="yes" />
<xsl:strip-space elements="*"/>
<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
<xsl:template match="/">
<xsl:call-template name="disappearance-act" />
</xsl:template>
<xsl:template name="disappearance-act">
<axsl:stylesheet
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl" >
<xsl:attribute name="version">1.0</xsl:attribute>
</axsl:stylesheet>
</xsl:template>
</xsl:stylesheet>
Итак, вы 'Вам нужно будет избегать этого, если вы хотите преобразовать ваш схематрон в XSL с Java. Так как скелет использует EXSLT только в одном месте из-за функции exsl: node-set, которая используется для создания атрибута пространства имен в handle-НамаШаблон espace Я избежал этой проблемы, просто переместив этот шаблон во внешнюю таблицу стилей, а затем включив его в скелет.Если исчезающее пространство имен указано только для сгенерированного элемента xsl: stylesheet, проблема просто исчезнет.Что касается того, почему это может происходить ... Я понятия не имею.Возможно, кто-то более опытный в XSLT сможет ответить на этот вопрос.
Далее (нет, еще не сделано) вы должны знать о том факте, что в Xalan возникает ошибка, когда вы используете функцию available ('exsl: node-set ') "в тесте где угодно (это именно то, что делается в дескрипторном пространстве имен). Тест вернет false, даже если эта функция довольно четко реализована и поддерживается Xalan. Поэтому не используйте это.Я решил ее, просто предположив, что эта функция существует, и не выполняя тест в шаблоне handle-namespace (это также делает все остальные xsl: выбирать ветви в этом шаблоне избыточными, поэтому я просто удалил их тоже). Ниже вы найдете всеизменения, которые я сделал, чтобы получить пример схемы из моего вопроса для правильного преобразования. Обратите внимание, что я не знаю, есть ли другие проблемы с сгенерированной таблицей стилей. Это только решает проблему в моем вопросе.
ЧастиСхематрон скелет XSL, который я изменил:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias"
xmlns:sch="http://www.ascc.net/xml/schematron"
xmlns:iso="http://purl.oclc.org/dsdl/schematron" >
<!--Removed no longer neccessary stuff from root stylesheet-->
<xsl:output method="xml" omit-xml-declaration="no" standalone="yes"/>
<xsl:strip-space elements="*"/>
<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
<!--This was added.-->
<xsl:include href="namespaces.xsl"/>
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="iso:schema[@queryBinding='exslt']">
<axsl:stylesheet
xmlns:date="http://exslt.org/dates-and-times"
xmlns:dyn="http://exslt.org/dynamic"
xmlns:exsl="http://exslt.org/common"
xmlns:math="http://exslt.org/math"
xmlns:random="http://exslt.org/random"
xmlns:regexp="http://exslt.org/regular-expressions"
xmlns:set="http://exslt.org/sets"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="date dyn exsl math random regexp set str" >
<xsl:apply-templates select="iso:ns"/>
<xsl:attribute name="version">1.0</xsl:attribute>
<!--Irrelevant changes here in order to make this stylesheet runnable.-->
</axsl:stylesheet>
</xsl:template>
<xsl:template match="iso:ns">
<xsl:call-template name="handle-namespace" />
</xsl:template>
<!--handle-namespace template was removed here-->
</xsl:stylesheet>
Это содержимое вклФайл ude:
<!--namespaces.xsl-->
<!--The include stylesheet which handles the namespaces from schematron.-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:template name="handle-namespace">
<xsl:variable name="ns-dummy-elements">
<xsl:element name="{@prefix}:dummy" namespace="{@uri}"/>
</xsl:variable>
<xsl:variable name="p" select="@prefix"/>
<xsl:copy-of select="exsl:node-set($ns-dummy-elements)
/*/namespace::*[local-name()=$p]"/>
</xsl:template>
</xsl:stylesheet>
Это только обходной путь для моей проблемы.Я не считаю это полным ответом на мой вопрос, поэтому я не буду помечать его как ответивший, пока кто-то не объяснит, почему это пространство имен исчезает.
Редактировать: после публикации вопроса всписок рассылки xalan-j и прочтя его - EXSLT - я пришел к выводу, что исчезающее пространство имен - это то, что должно произойти.Атрибут extension-element-prefixes используется для предотвращения вывода пространств имен расширения в дерево результатов.Еще раз я обнаружил, что xsltproc не соответствует спецификациям XSLT 1.0.Это также означает, что скелет iso schematron находится в баге.Я бы с радостью сообщил об этом им, но их список рассылки, похоже, уступил спаму.