如何在xslt-transformer中动态(以编程方式)添加XSL资源?

时间:2016-05-17 07:42:51

标签: xml spring xslt spring-integration

我正在使用spring integration< xslt-transfomer 进行xml转换。 我的代码如下,

<int-xml:xslt-transformer id="xmlTransformer" input-channel="inputChannel" 
        output-channel="outputChannel"  xsl-resource="classpath:META-INF/OrderXslt.xsl" />

这里我想在运行时动态传递 xsl-resource =&#34; classpath:META-INF / OrderXslt.xsl&#34; 。我可以从上下文中获取 xmlTransformer bean,但无法弄清楚如何将 xsl-resource 设置为它。我的java代码就像,

File myFile = new File("D:\OrderXslt.xsl");
EventDrivenConsumer transformerConsumer =  (EventDrivenConsumer) ctx.getBean("xmlTransformer");

//I need to pass myFile to transformerConsumer instace.
//However I am unable to find any API of EventDrivenConsumer 
            which will accept xsl resource form here (i.e. myFile )

任何程序化解释都将受到高度赞赏。 提前谢谢。

修改

    public class TempTransformer<Object, Obejct> extends AbstractTransformer  {

    private volatile XsltPayloadTransformer xslt;

    protected Object doTransform(Message<?> message) throws Exception {
        return (Object) findorBuildTransformerForMessage(message).transform(message); 
//Its throwing error here as
//org.springframework.integration.transformer.MessageTransformationException: failed to transform message; nested exception is java.lang.NullPointerException
    }

    private Transformer findorBuildTransformerForMessage(Message<?> message{
    xslt = new XsltPayloadTransformer(new ClassPathResource("/META-INF/OrderXslt2.xsl"));
    return xslt;
    }

修改

我已按以下方式实施XsltPayloadTransformer

protected Message<?> doTransform(Message<?> message) throws Exception {
    xsltTransformer = new XsltPayloadTransformer(new ClassPathResource("D:/sample.xsl"));

    this.xsltTransformer.setResultType("StringResult");
    this.xsltTransformer.afterPropertiesSet();
    return this.xsltTransformer.transform(message);

    }

但是我没有得到正确的输出。另一方面,我有一个简单的java程序,它使用Saxon实现并显示正确的输出。这是......

 public static void main(String [] arr) {

    TransformerFactory tFactory = TransformerFactory.newInstance();
    StreamSource xmlInputFile = new StreamSource("D:/input.xml");
    StreamSource xslTransformationFile = new StreamSource("D:/sample.xsl");
    StreamResult xmlOutputFile = new StreamResult(new File("D:/output.xml"));
    Transformer transformer;
    try {
        transformer = tFactory.newTransformer(xslTransformationFile);  //gives instance of net.sf.saxon.jaxp.TransformerImpl 
        transformer.transform(xmlInputFile, xmlOutputFile);
    } 
    } catch (Exception e) {

    }

    }

我无法弄清楚我错过了什么。还有什么我需要设置为XsltPayloadTransformer ??或者我错过了什么?  我正在使用 XSL v2 spring 4.1.7 spring integration 4.1.8 vesrions。

1 个答案:

答案 0 :(得分:1)

涉及3个类,EventDrivenConsumerMessageTransformingHandler(消费者的属性handler)和XsltPayloadTransformer - transformer属性处理程序。

XsltPayloadTransformer目前没有API来更改资源,它是在构造函数参数中提供的,因此您必须创建一个新的。

MessageTransformingHandler没有用于更改变换器的API - 它的最终版本和构造函数arg。因此,您必须创建一个新的。

EventDrivenTransformer没有API来更改处理程序,它是最终的,也是构造函数arg。

所以,最重要的是,你不能用标准的开箱即用消费者做你想做的事。

但是,您可以创建自己的bean,委托给XsltPayloadTransformer,您可以根据需要替换为新的XsltPayloadTransformer。请确保如果以编程方式创建afterPropertiesSet(),则必须致电Templates,因为设置已完成。

API for the EventDrivenConsumer is here但由于上述原因,它无法帮助您。

您还可以使用<int:transformer ... ref="myTransformer" /> public class Foo<Object, Object> extends AbstractTransformer<T, U> { private final ConcurrentMap<String, Transformer> xslts = new ConcurrentHashMap<>(); protected Object doTransform(Message<?> message) throws Exception { return findorBuildTransformerForMessage(message).transform(message); } private Transformer findorBuildTransformerForMessage(Message<?> message) { // retrieve from map or create and add it to map } } 选项并编写自己的包装器来动态更改资源。

修改

var mycell = sheet.getActiveSelection();  
var cellcol = mycell.getColumn() ;
var cellrow = mycell.getRow();

sheet.setActiveCell(sheet.getDataRange().offset(0, 0,cellcol, cellrow));