【问题标题】:Why is concat randomly duplicating output in this XSLT transformation?为什么 concat 在此 XSLT 转换中随机复制输出?
【发布时间】:2015-10-23 15:37:53
【问题描述】:

我正在使用 XSLT 将 HTML 转换为 XSL-FO。我们正在从 HTML 转换为 XSL-FO 的事实可能与回答这个问题无关。

对于我的几个使用concat 作为字体大小和高度的值,concat 的输出会随机复制一次调用。

示例:对于以下代码,$lineheight-td 的值为 13

<fo:block line-height="{concat($lineheight-td, 'pt')}">

这是我通常会收到的预期正确输出:

<fo:block line-height="13pt">

这是我大约 1% 的时间收到的错误输出:

<fo:block line-height="13pt13pt">

这是我收到的错误输出

<fo:block line-height="13pt&#0;&#0;&#0;&#0;">

(注意意外的输出是 4 个字符('1''3''p''t')和意外的 '&amp;#0;' 产生了 4 次)。

这些重复的输出是由 concat 调用在不同位置从同一输入 HTML 文件在不同迭代中生成的。

我目前的解决方法是如果输出不好就重新转换;到目前为止,这解决了问题,并证明这与数据无关,但首先不应该发生重复输出。我在多线程 Java 环境下运行,但我为每个单独的转换调用使用了一个新的 Transformer,来自在应用程序启动时初始化一次的共享 Template

为什么 concat 会出现这种情况,我该如何解决?

应用程序使用较旧的 Xalan 库 (2.7.0)。我将研究 Xalan 错误并升级到 Xalan 2.7.1 或更高版本。

环境:

JBoss 7.2.0
JRE 1.7.0_45
xalan-2.7.0
xml-apis-1.3.04
xml-apis-ext-1.3.04

Java 代码:

String inputData = ...; // OUR HTML

Templates template = (Templates)templatesMap.get("HTML2FO");
Transformer transformer = template.newTransformer();
StreamSource streamSource = new StreamSource(new StringReader(data));
StringWriter writer = new StringWriter();
transformer.transform(streamSource, new StreamResult(writer));

String outputData = writer.toString();  // OUR FO

【问题讨论】:

  • 尝试使用 Apache Xerces 而不是 JDK 版本的 Xerces 作为您的 XML 解析器。 JDK 版本中存在一个长期存在的错误,它偶尔会破坏属性值。我不知道输入属性值的损坏是否可以解释您所看到的症状,但值得一试。
  • 我觉得最新的版本是2.11.0,应该放在“endorsed”目录下。如果这对您没有任何意义,请搜索“Xerces 认可目录”。

标签: java xslt concat xalan


【解决方案1】:

应用程序使用较旧的 Xalan 库 (2.7.0)。 我将研究 Xalan 错误并升级到 Xalan 2.7.1 或更高版本。

Xalan 版本发布说明只列出了没有描述的错误编号,并且在发布 Xalan 2.7.1 后的某个时间点,Xalan 开发切换到了不同的错误跟踪器。有关他们旧的“已修复”错误的信息已经消失。

没有什么可以“证明”任何给定库存在问题,我最终将所有与 XML 和转换相关的 JAR 文件更新为以下版本:

JAR FILE NAME           VERSION
serializer.jar          2.7.2
xalan.jar               2.7.2
xerxesImpl.jar          2.11.0
xml-apis.jar            1.4.01
xml-apis-ext.jar        1.4.01

对于使用原始 XML 库的约 8,000 次转换,我的成功率达到了 99%;失败的文件在第二次迭代中成功重新处理,这表明问题与我的数据无关。

对于使用更新的 XML 库进行的约 11,500 次转换,我的成功率达到了 100%。

我会继续测试,但我可以得出结论,更新所有库似乎已经解决了问题。

【讨论】:

  • 您认为其中一个库的早期版本之一可能是线程安全问题吗?
  • @kjhughes - 不;我最近在这方面将代码重构为多线程,并打破我们的步骤来解决这样的问题。旧的单线程系统只是失败了(或通过可能失败的文件进入另一个步骤)并从头开始重试。我们偶尔会遇到这些错误,但永远无法追踪到它们。我很确定这是库代码设置属性值的问题。
猜你喜欢
  • 2020-06-13
  • 2019-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多