【问题标题】:Camel XSLT transformationCamel XSLT 转换
【发布时间】: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 负载

【问题讨论】:

    标签: xslt apache-camel xslt-1.0 transform xslt-2.0


    【解决方案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,您可以调用它
        猜你喜欢
        • 2018-06-15
        • 1970-01-01
        • 2023-04-07
        • 2012-07-18
        • 2019-10-06
        • 2019-12-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多