首页 > 解决方案 > 什么导致 javax.xml.transform.* 中的致命错误、错误和警告

问题描述

我有一段代码,可将 XML 文件和 XSLT 文件转换为 HTML。我正在尝试在ErrorListener中测试每个案例(致命错误、错误和警告),但我找不到任何文档说明导致其中任何一个的原因。

我曾尝试在我的文档中故意犯错误,但我只得到 [致命错误]。

我拥有的代码在 TransfomerFactory 和 Transformer 中使用相同的 ErrorListener。

private String convertXmlToHtml(Source xml, Source xslt) throws TransformerException {
    StringWriter sw = new StringWriter();
    TransformerFactory tFactory = TransformerFactory.newInstance();
    ErrorListenerThrowOnFatal errorListener = new ErrorListenerThrowOnFatal();
    tFactory.setErrorListener(errorListener);

    Transformer transform = tFactory.newTransformer(xslt);
    transform.setErrorListener(errorListener);
    transform.transform(xml, new StreamResult(sw));

    return sw.toString();
}

当错误/警告不是致命的时,具体的场景是什么?

编辑:场景应该是输入文件中的错误/警告。ei TransformerFactory.newTransformer() 或 Transformer.transform() 何时会创建错误/警告。

标签: javaxmlxslt

解决方案


ErrorListener 的文档与 XSLT 1.0 规范的术语不是特别一致,与以后的版本更不一致。这部分是因为 JAXP API 的设计者试图从 XSLT 中抽象出来,认为它也可以与其他转换语言一起使用,但实际上从未发生过。因此,解释将取决于特定 XSLT 处理器的实现者。

我相信一个处理器至少会选择性地将 xsl:message 输出发送到 ErrorListener.warning() 方法,但这对我来说总是很奇怪,因为 xsl:message 输出是 XML,而不是字符串。

另一个因素是,无论是 ErrorListener 设计还是 XSLT 1.0 规范都没有仔细区分静态错误和动态错误,两者的处理确实需要有所不同。(实际上,设计的弱点之一是样式表中的静态错误不需要表示为 Java 异常。)

我的解释是:

警告:根据规范,您没有做错任何事情,但处理器想要告诉您您可能正在做一些不受欢迎或无意的事情的情况。一个例子可能是导航到属性节点的子节点(它永远不会做任何有用的事情)。

错误:违反规范中的规则,但可以继续处理(至少在寻找进一步错误的程度上)。这很好地包括了所有静态(编译时)错误,以及那些在 XSLT 1.0 规范中明确表示为“可恢复错误”的动态错误(例如模版规则匹配不明确)。(“可恢复错误”的概念在后来的规范版本中消失了)。

致命错误:任何事情,无论规范中是否有规则,执行都无法继续。包括大多数动态错误,例如在 1.0 中将 sum() 应用于不是节点集的东西。


推荐阅读