gpt4 book ai didi

java - xsl :apply-templates/xsl:with-param with Xalan-J and saxon compared to xsltproc 的意外行为

转载 作者:行者123 更新时间:2023-11-30 09:40:58 25 4
gpt4 key购买 nike

我正在尽最大努力学习如何通过 Java 代码使用 XSLT 1.0,但随着时间的推移,我开始慢慢地失去理智。

我的类路径上有 Xalan-J(xalan.jar 和 xsltc.jar 以及所有依赖项 jar)、saxon 和 jing(后两者在我的项目中的其他地方使用),并且我将 JAXP 与 System. setProperty 调用以按照我想要的方式强制使用类实现,例如 TransformerFactory。这也使我能够通过简单地更改代码中的属性来了解不同的 XSLT 处理器使用单个 XSL 转换文件的行为方式。此外,我还使用 cygwin 环境中的 xsltproc 来查看它的作用。我还在 Oxygen 中进行调试,以确保我的 Java 代码没有问题。

看看这个虚拟 XSL:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:rng="http://relaxng.org/ns/structure/1.0"
xmlns:ex="http://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="http://relaxng.org/ns/structure/1.0"
xmlns:ex="http://example.com/ns/ex"
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
<start>
<grammar ex:subgram="something" ns="http://example.com/ns/something">
<start>
<ex:data>
<optional />
</ex:data>
</start>
</grammar>
</start>
</grammar>

我不知道自己做错了什么,但传递 XSL 中唯一变量的值仅适用于 xsltc 和 xsltproc。正常的 xalan 和 saxon 都无法传递该值。请参阅下面的结果。

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 标准?有没有我可以用来让它工作的解决方法?

最佳答案

解释很简单:

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

rng:optionalex:data 的子项。

ex:data中没有模板匹配,因此由元素节点的XSLT内置模板处理。

当然,内置模板对传递给它的参数一无所知,因此它不会将它们传递给它应用的下一个模板。

因此,匹配 rng:optional(以上)的模板被选择由 XSLT 内置元素模板执行,并且没有参数被传递到这个选定的模板。

因此,parameter param 的值为空字符串,您从 Saxon 和 XalanJ 都获得了正确的输出。

关于java - xsl :apply-templates/xsl:with-param with Xalan-J and saxon compared to xsltproc 的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9210159/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com