【问题标题】:How to use Saxon with Wildfly properly?如何正确使用 Saxon 和 Wildfly?
【发布时间】:2018-03-22 05:51:46
【问题描述】:

我对 Saxon 和 WildFly 10.0.0.Final 有疑问。我写了一些 XSLT,它们在我运行单元测试时可以正常工作,但是当我在 Wildfly 上运行相同的代码时遇到了问题。

在我的 pom.xml 我有这样的依赖:

 <dependency>
    <groupId>net.sf.saxon</groupId>
    <artifactId>Saxon-HE</artifactId>
    <version>9.8.0-4</version>
</dependency>

我尝试了几个版本的 Saxon,甚至将它换成 Xalan,但我仍然遇到同样的问题。它适用于单元测试,但不适用于 Wildfly。问题是“Wildfly 案例”只是忽略了 XSLT 的某些部分。例如这部分被忽略:

<xsl:for-each select="$var33_Tracking/ns0:PartyIdentification/ns0:Location">
   <xsl:variable name="var13_LatLong" as="node()" select="ns0:LatLong"/>
   <xsl:variable name="var12_cur_as_string" as="xs:string" select="fn:string($var13_LatLong)"/>
   <xsl:variable name="var14_result" as="xs:string?">
      <xsl:choose>
         <xsl:when test="(fn:string(fn:string-length($var12_cur_as_string)) &gt; '0')">
            <xsl:sequence select="$var12_cur_as_string"/>
         </xsl:when>
         <xsl:otherwise>
            <xsl:for-each select="ns0:GeoLoc">
               <xsl:sequence select="fn:string(.)"/>
            </xsl:for-each>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:variable>
   <xsl:for-each select="$var14_result">
      <LatitudinalHemisphere>
         <xsl:choose>
            <xsl:when test="(fn:substring-before(., ',') &lt; '0')">
               <xsl:sequence select="'S'"/>
            </xsl:when>
            <xsl:otherwise>
               <xsl:sequence select="'N'"/>
            </xsl:otherwise>
         </xsl:choose>
      </LatitudinalHemisphere>
   </xsl:for-each>
</xsl:for-each>

它看起来像一些功能: fn:string-lengthfn:substring-before 可能会导致此问题,但我无法弄清楚如何解决该问题。有什么想法或提示吗?

【问题讨论】:

  • 如果这里有人甚至可以在没有任何关于您如何尝试在 Wildfly 中使用受影响的 XSLT 的信息的情况下开始回答,我会感到惊讶。一般来说,“一些信息”应该是minimal reproducible example。我承认这对于部署在应用程序服务器中的东西来说可能很困难,但你当然可以提供更多的上下文和更少的繁琐。

标签: xslt wildfly saxon


【解决方案1】:

我从来没有听说过 Wildfly,更不用说有任何专业知识了,所以我能做的最好的就是提供一些诊断建议(向那些认为这不是“答案”的纯粹主义者道歉,但它也是期待评论。)

首先,找出普通样式表是否正确运行,以及它们是否真的在 Saxon 下运行。一种简单的方法是使用样式表

<xsl:template match="/">
  <p>Transformed using <xsl:value-of select="system-property('xsl:vendor')"/></p>
</xsl:template>

如果可行,您可以查看更多系统属性以确定 Saxon 版本(我在上面的建议故意避免使用 XSLT 2.0 中添加的任何系统属性)。

你能看到xsl:message 的输出吗?您可以选择诊断:您可以使用xsl:message 显示它们,也可以将它们(当然是暂时的)包含在结果文档中。您采用哪种方法取决于您的运行时环境的破坏程度。

如果简单的事情正在工作,但您向我们展示的代码“忽略”了所示的 xsl:for-each 指令,那么第一个也是最明显的可能性是 select 表达式的计算结果为空序列。编译器甚至有可能删除了表达式,因为它已经决定表达式将始终计算为空序列。我将从显示应用于表达式的 count() 开始:

count($var33_Tracking/ns0:PartyIdentification/ns0:Location)

要查看的另一件事是系统是否真的在为您提供诊断,而您没有看到它们。例如,他们可能会去某个地方的日志文件。

您说您怀疑使用 fn:string() 之类的函数与此有关。你能追究这种怀疑并弄清楚它是否有道理吗?这里唯一不寻常的是您使用了“fn”前缀,这在 XSLT 中从来没有必要。我不明白为什么这会在某些环境中而不是其他环境中导致失败,但请检查是否正确声明了“fn”前缀,并看看如果将函数调用更改为无前缀会发生什么。

值得注意的是,可以使转换在不同环境中产生不同结果的因素,并消除这些可能的原因:

  • 提供了不同的源文档或样式表参数

  • 节点具有不同的基本 URI

  • 不同的 XSLT 软件版本或配置

  • 不同的 XML 解析器(尽量避免使用有缺陷的 JDK 解析器:优先使用 Apache Xerces)

  • 对本质上依赖于实现的事物的意外依赖,例如不同 XML 树中节点的文档顺序,属性顺序

  • 对当前时区或默认语言的意外依赖

你可能觉得你已经消除了这些原因,但我不得不问这个问题,因为你没有给我任何可以让我消除它们的证据。

【讨论】:

  • 非常感谢您的回答。我会尽快检查一下,让您知道它对您有什么帮助。
猜你喜欢
  • 2023-03-17
  • 1970-01-01
  • 2018-12-21
  • 1970-01-01
  • 2019-01-31
  • 2023-04-03
  • 2018-12-04
  • 2015-09-23
  • 2020-07-02
相关资源
最近更新 更多