Camel XSLT 转换
Posted
技术标签:
【中文标题】Camel XSLT 转换【英文标题】:Camel XSLT transformation 【发布时间】:2018-09-08 22:43:52 【问题描述】:我正在尝试使用 XSLT 组件从 XML 进行动态转换。是否可以将 URI 中的 java 变量作为 XSLT 模板传递? 例如:
from("direct:foo").
to("xslt:$fee").
to("direct:output");
foo - 是一个 XML 有效负载, fee - 存储为 java.lang.String 的 XSLT 模板, 输出 - xml 负载
【问题讨论】:
【参考方案1】:您可以通过某些条件将变量分配到消息头中:
.setHeader("TemplateLocation").constant("OSGI-INF/xsl/pretty.xsl")
之后,您可以使用收件人列表 EIP:
.recipientList().simple("xslt:$header.TemplateLocation")
或者你可以使用toD:
.toD("xslt:$header.TemplateLocation")
工作示例:
@Override
protected RouteBuilder createRouteBuilder()
return new RouteBuilder()
@Override
public void configure() throws Exception
from("direct:start")
.routeId("xsltTest")
.log(LoggingLevel.INFO, "XML input : \n$body")
.setHeader("TemplateLocation").constant("OSGI-INF/xsl/pretty.xsl")
//.recipientList().simple("xslt:$header.TemplateLocation")
.toD("xslt:$header.TemplateLocation")
.to("log:end?level=INFO&showAll=true&multiline=true");
;
据我所知,没有办法将字符串变量用作 xslt 模板。
【讨论】:
我没有像“OSGI-INF/xsl/pretty.xs”这样的静态模板。我将在请求中获取 pretty.xs 有效负载并将其传递给转换。 也许您可以将 xlst 模板保存到外部文件,然后将其名称分配到消息头中,如上所示。也可能是一个有用的 contentCache=false 选项。 在多线程环境中如果我为每个请求创建 XSL 文件,它会变得一团糟。我不想那样做。是否有任何明确的方法可以将请求正文传递给 XSLT 组件? 与您在文档中所需要的完全不同。例如,仅当您开发自己的处理器时。在其中使用标准 Java 工具(TransformerFactory、StreamSource)。在消息正文或标头中传递 xslt 模板,或使用内容丰富器 EIP 将模板加载到您自己的处理器中。【参考方案2】:据我所知
您的 XSLT 轮询器有一个动态表达式作为子目录 ($fee)。 据我所知,您不能在骆驼中获得动态地址 路线。因为这意味着您可以从多个 端点。您可以将其作为单独的文件并像这样调用它 to("xslt:file:///foo/bar.xsl")。
更多详情XSLT
【讨论】:
【参考方案3】:您不能将动态样式表(动态内容)与 Camel 的 XSL 组件一起使用。
您可以做的最动态的事情是对静态文件的动态引用,如下所示:
.toD("xslt:$expressionWithFileReference")
然而,你可以简单地调用一个Java bean来做你想做的事并从路由中调用它:
.bean(javaBeanReference or new YourJavaBean())
在 Bean 中,您可以使用 Camel annotations 将标头、属性和主体注入方法中。从当前的 Camel Exchange 中满足您的任何需求。
public void yourMethod(
@Header(headername) String parameterName,
@Body Type parameterName)
...
【讨论】:
【参考方案4】:由于 Camel 不支持动态 XSLT 输入流,我必须创建自己的 Transformer。这可能会帮助某人
这是我的代码 sn-p。我使用如下骆驼处理器
@Override
public void process(Exchange exchange) throws Exception
XmlMapper xmlMapper = new XmlMapper();
Target target = xmlMapper.readValue(transform(getInputStreamFromDocument(xmlPayload), new ByteArrayInputStream(xsltTemplate.getBytes())), target.class);
public byte[] transform(InputStream dataXML, InputStream inputXSL)
throws TransformerException
ByteArrayOutputStream bos = new ByteArrayOutputStream();
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new StreamSource(inputXSL));
StreamSource in = new StreamSource(dataXML);
StreamResult out = new StreamResult(bos);
transformer.transform(in, out);
return bos.toByteArray();
【讨论】:
如何在骆驼中调用它? 以上更新。使用骆驼处理器/bean,您可以调用它以上是关于Camel XSLT 转换的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Apache Camel 在 XSLT 中为每个组申请
原因:org.apache.camel.NoTypeConversionAvailableException:没有可用于从类型转换的类型转换器:POJO 到 byte[]
如何在 R 中将 not.camel.case 转换为 CamelCase