2016-05-17 59 views
1

我使用彈簧集成的xslt-transfomer進行xml轉換。 我的代碼是像下面,如何在xslt-transformer中動態(以編程方式)添加XSL資源?

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

這裏我想通過XSL-資源=:在運行時 「classpath中META-INF/OrderXslt.xsl」動態。我能夠從上下文獲得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 v2spring 4.1.7spring integration 4.1.8 vesrions。

回答

1

有涉及3班,EventDrivenConsumerMessageTransformingHandler(消費者的財產handler)和XsltPayloadTransformer - 處理程序的transformer財產。

XsltPayloadTransformer目前沒有API來更改資源,它在構造函數參數中提供,因此您必須創建一個新的資源。

MessageTransformingHandler沒有API來更改變換器 - 它是最終的和一個構造函數arg。所以你必須創建一個新的。

EventDrivenTransformer沒有更改處理程序的API,它是final和構造函數arg。

因此,底線是你不能做你想要的與標準的現成的消費者。

但是,您可以創建自己的bean,並委派給XsltPayloadTransformer,您可以根據需要使用新的bean替換它。只要確保如果以編程方式創建XsltPayloadTransformer,則必須調用afterPropertiesSet(),因爲這是安裝完成的地方。

API for the EventDrivenConsumer is here但它不會幫助你出於上述原因。

您也可以使用Templates選項並編寫自己的包裝來動態更改資源。

編輯

<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 
    } 
} 
+0

@GarryRussell感謝您的解釋,但我仍然很困惑與XsltPayloadTransformer的代表團和我應該怎麼用新的更換。 –

+0

請參閱我的編輯示例,但我認爲我會使用模板方法。 –

+0

@Garry我需要一個線程安全的方法。如何使用 Transformer註釋是線程安全的,我可以使用該實現嗎? (請看最新的編輯) –

相關問題