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[]

为啥在 XSLT 转换期间出现此错误:XSLT 转换失败?

如何在 R 中将 not.camel.case 转换为 CamelCase

xslt 不会选择在 XSLT 转换中动态更改名称空间以进行进一步转换

使用 C# 将 JSON 字符串从 Camel 案例转换为 Pascal 案例