SAXTransform链中的第二个XSLT似乎没有做任何事情

时间:2012-07-12 21:59:51

标签: java xslt sax

在我详细介绍具体细节之前,我之前尝试过使用Oracle的parser.v2 XSLT库并遇到同样的问题(参见my first question)。但是,当我使用C#时,它工作正常。

// from the example I see everywhere on the internet
SAXTransformerFactory stf = (SAXTransformerFactory)TransformerFactory.newInstance();

Templates t_cctagstrip = stf.newTemplates(new StreamSource(new FileInputStream("C:\\path\\to\\first.xsl")));
Templates t_cctable = stf.newTemplates(new StreamSource(new FileInputStream("C:\\path\\to\\second.xsl")));

TransformerHandler th1 = stf.newTransformerHandler(t_cctagstrip);
TransformerHandler th2 = stf.newTransformerHandler(t_cctable);

// transform 1 pipes into transform 2
th1.setResult(new SAXResult(th2));

// transform 2 pipes to System.out
th2.setResult(new StreamResult(System.out));

Transformer t = stf.newTransformer();
t.transform(new StreamSource(new FileInputStream("C:\\path\\to\\source.xml")), new SAXResult(th1));

我在想,问题可能在于第一个转换的输出是一个根文本的文本片段?

text at root level
<tag> ... tags that need extra processing ... </tag>
more text at root level

C#如何处理变换有什么不同之处吗?它没有失败或给我任何警告,我可以告诉。它只是没有改变任何东西。

1 个答案:

答案 0 :(得分:1)

您在第一个问题中没有提到您遇到的实际问题,例如提供任何日志消息等,因此无法知道您的XSLT转换失败的原因。但在第二个问题中,你清楚地揭示了事情失败的原因。

通常,XSLT转换要求所有已解析的内容至少格式良好的XML。如果源文档没有包含“root”元素(实际上称为文档元素),那么它不是格式良好的XML,因此不是XML定义,因此不适合XML处理。

作为一种解决方案,如果您可以将第一个转换的输出包装在文档元素中,则可以继续将其解析为XML。然后,您可以通过非XML过程将其剥离。

在这方面,Java或C#之间没有任何区别。如果第一次转换的输出不是格式良好的XML,那么C#不应该接受它作为XML。我无法解释为什么会这样做 - 如果C#的XML处理器接受了非格式良好的XML,那么它将是不合规的。我想你没有得到任何输出的原因是转换只是由于非XML源而失败。为了找出实际发生的情况,您可以在Transformer上设置javax.xml.transform.ErrorListener,并在ErrorListener中将所有内容转储到日志中。

(作为一个切线,你还说你需要使用Oracle的XSL处理器。真的吗?我假设Oracle的实现中必须有一些不可用的功能在Xalan或Saxon中,因为你要将代码绑定到实现而不是使用JAXP API,这当然不是推荐的做法。在编写API时调试问题可能更好,以确保它们不是实现 - 依赖,因为你无法更改实现的内部代码,最好只调试自己的缺陷,而不是Oracle的。但鉴于上面的示例代码似乎使用JAXP API,我会假设问题你实际上并没有绑定到Oracle的XSLProcessor。)