Я изо всех сил пытаюсь научиться использовать XSLT 1.0 из java-кода, но постепенно постепенно теряю рассудок.
У меня есть Xalan-J (как xalan.jar, так и xsltc.jar со всеми банками зависимостей), saxon и jing (последние два используются в другом месте в моем проекте) в моем пути к классам, и я использую JAXP с комбинацией вызовов System.setProperty для принудительно использовать реализации классов, такие как TransformerFactory, как я хочу. Это также позволяет мне видеть, как разные процессоры XSLT ведут себя с использованием одного файла преобразования XSL, просто изменяя свойства из кода. Кроме того, я также использую xsltproc из среды cygwin, чтобы посмотреть, что он делает. Я также отлаживаю в Oxygen, чтобы убедиться, что мой Java-код не является проблемой.
Взгляните на этот фиктивный XSL:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="https://www.w3.org/1999/XSL/Transform"
xmlns:rng="https://relaxng.org/ns/structure/1.0"
xmlns:ex="https://example.com/ns/ex"
version="1.0">
<xsl:output method="xml" encoding="utf-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<!-- Start by finding the root grammar element -->
<xsl:apply-templates select="rng:grammar"/>
</xsl:template>
<xsl:template match="/rng:grammar">
<!-- Continue with child grammar elements -->
<xsl:apply-templates select="descendant::rng:grammar"/>
</xsl:template>
<xsl:template match="rng:grammar">
<!-- set the variable and pass it's value to another template -->
<xsl:variable name="parameter" select="'any-string-value'"/>
<xsl:message>initial value: <xsl:value-of select="$parameter"/></xsl:message>
<xsl:apply-templates select="descendant::ex:data">
<xsl:with-param name="parameter" select="$parameter"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="rng:optional">
<!-- use the param value here -->
<xsl:param name="parameter"/>
<xsl:message>final value: <xsl:value-of select="$parameter"/></xsl:message>
</xsl:template>
</xsl:stylesheet>
Он ничего не делает, кроме вызова некоторых шаблонов, которые работают с этим фиктивным документом экземпляра XML:
<?xml version="1.0" encoding="UTF-8"?>
<grammar
xmlns="https://relaxng.org/ns/structure/1.0"
xmlns:ex="https://example.com/ns/ex"
datatypeLibrary="https://www.w3.org/2001/XMLSchema-datatypes">
<start>
<grammar ex:subgram="something" ns="https://example.com/ns/something">
<start>
<ex:data>
<optional />
</ex:data>
</start>
</grammar>
</start>
</grammar>
Я не знаю, что делаю неправильно, но передача значения единственной переменной в этом XSL работает только с xsltc и xsltproc. И нормальный ксалан, и саксон не могут передать значение. См. Результаты ниже.
xsltproc:
$ xsltproc transformation.xsl instance.xml
initial value: any-string-value
final value: any-string-value
Скомпилированный процессор Xalan (xsltc, а также с реализацией по умолчанию java 1.6):
Implementation: org.apache.xalan.xsltc.trax.TransformerFactoryImpl loaded from: ./lib/xalan-j_2_7_1/xsltc.jar
initial value: any-string-value
final value: any-string-value
Интерпретирующий процессор Xalan (xalan):
Implementation: org.apache.xalan.processor.TransformerFactoryImpl loaded from: ./lib/xalan-j_2_7_1/xalan.jar
initial value: any-string-value
final value:
саксон:
Implementation: com.icl.saxon.TransformerFactoryImpl loaded from: ./lib/saxon6-5-5/saxon.jar
initial value: any-string-value
final value:
Мне это нужно для работы с xalan (причина - приемлемая поддержка EXSLT). Понятия не имею, в чем может быть причина разных результатов. Я пытался, что все эти процессоры реализуют XSLT 1.0, но думаю, что они делают это по-разному. То, что я пытаюсь сделать в своем XSL, несовместимо с XSLT 1.0? Есть ли обходной путь, который я мог бы использовать, чтобы заставить это работать?
ex:data
, в котором объявлен параметр и который будет передавать его через свойxsl:apply-templates
09.02.2012