如何在 Java 中链接 XSLT 处理器?
Posted
技术标签:
【中文标题】如何在 Java 中链接 XSLT 处理器?【英文标题】:How to chain XSLT processors in Java? 【发布时间】:2021-12-16 13:35:38 【问题描述】:我想用 Java 中的几个 XSLT 转换器执行链式 XML 处理。第一个转换器将输入作为javax.xml.transform.Source
并产生javax.xml.transform.Result
。不是我想将结果用作下一次转换的输入。 IE。我需要第二次转换的来源。
如何从Result
创建Source
(如果可能的话)?还是有其他解决方案可以解决我想做的事情?
【问题讨论】:
如果没记错的话,输入不是转换 XML 吗? Transform 的输出不也是 XML 吗?您不能直接从Result
对象中获取XML,然后将其分配给下一个Source
对象吗?
创建第二个 XSLT 作为 SAX TransformerHandler 并将其作为 SaxResult 提供给第一个 Transformer。
【参考方案1】:
一种方法是将第二个转换设置为 Sax TransformerHandler
作为第一个 Transformer
的 SAXResult
的 ContentHandler,例如:
TransformerFactory transformerFactory = TransformerFactory.newInstance();
String xslt1 = "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'><xsl:template match='/'><xsl:call-template name='identity'/><xsl:comment>sheet 1</xsl:comment></xsl:template><xsl:template name='identity' match='@* | node()'><xsl:copy><xsl:apply-templates select='@* | node()'/></xsl:copy></xsl:template></xsl:stylesheet>";
String xslt2 = "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'><xsl:template match='/'><xsl:call-template name='identity'/><xsl:comment>sheet 2</xsl:comment></xsl:template><xsl:template name='identity' match='@* | node()'><xsl:copy><xsl:apply-templates select='@* | node()'/></xsl:copy></xsl:template></xsl:stylesheet>";
Transformer transformer1 = transformerFactory.newTransformer(new StreamSource(new StringReader(xslt1)));
TransformerHandler transformer2 = ((SAXTransformerFactory)transformerFactory).newTransformerHandler(new StreamSource(new StringReader(xslt2)));
transformer2.setResult(new StreamResult(System.out));
transformer1.transform(new StreamSource(new StringReader("<root><item>a</item><item>b</item></root>")), new SAXResult(transformer2));
或者您可以将 XSLT 转换链接为 SAX XMLFilter
s: https://saxonica.plan.io/projects/saxon/repository/he/revisions/master/entry/latest10/samples/java/he/JAXPExamples.java#L694
【讨论】:
非常酷,谢谢!这样就可以链接任意数量的 XSL 进程。只需将 SAXResult 添加到链中!我唯一不太喜欢的是对SAXTransformerFactory
的沮丧。我们能始终确保我们得到它的一个实例吗?
@fml2,我认为您可以先检查该功能是否受支持,我需要查看 API 规范才能说明这一点,或许您可以查看 github.com/apache/xalan-java/blob/master/samples/Pipe/…
我想我可以检查是否transformerFactory instanceof SAXTransformerFactory
,如果没有,使用序列化到字符串。我希望这永远不会发生。
@fml2,我不知道所有不同的 Java JRE 和 JDK(Oracle、IBM 等?)以及它们的内置 XSLT TransformerFactory 实现,足以判断您是否可以期望 SAXTransformerFactory支持,我认为 Xalan 支持,Saxon 也支持。以上是关于如何在 Java 中链接 XSLT 处理器?的主要内容,如果未能解决你的问题,请参考以下文章