2012-05-23 39 views
0

由於從這個問題在我的思維模式的延續:Saxon in Java: XSLT for CSV to XML撒克遜在Java中:XSLT代碼重用

每邁克爾·凱關於這個問題的答案,我終於結束了對應用XSLT到文檔下面的代碼:

Processor processor = new Processor(false); 
StringWriter stringWriter = new StringWriter(); 
Serializer serializer = new Serializer(stringWriter); 
XsltCompiler compiler = processor.newXsltCompiler(); 
XsltExecutable executable = compiler.compile(new StreamSource(new File(transformLocation))); 
XsltTransformer transformer = executable.load(); 
transformer.setInitialTemplate(new QName("main")); 
transformer.setParameter(new QName("filePath"), new XdmAtomicValue("location/of/Test.csv")); 
transformer.setDestination(serializer); 
transformer.transform(); 
String transformedDocument = stringWriter.toString().trim(); 

該代碼使用撒克遜的s9api的(我在9.4 HE版本)。它允許我設置初始模板並動態地將路徑注入要轉換的文檔,這使我能夠轉換非XML文件(例如在這種情況下爲CSV)。

但是,這有點抹殺了我的代碼重用性。我有一個transformDocument()方法。最初,在我嘗試執行轉換CSV之類的瘋狂操作之前,僅使用XML,它被我的marshalObjectToDocument()unmarshalDocumentToObject()方法(有可重用性)調用。

這裏只給出XML的世界上兩個方向的比較:

  1. unmarshalDocumentToObject()
    • 我開始有它內部的文檔的文件。
    • 我這樣做:new StreamSource(new File(documentLocation))
    • StreamSource可以傳遞給transformDocument 「源」(XsltTransformer.setSource())。
  2. marshalObjectToDocument()
    • 我開始對某種對象。
    • 這被封送到一個巨大的XML字符串中。
    • 我這樣做:new StreamSource(new StringReader(giantStringOfXML))
    • StreamSource可以傳遞給transformDocument 「源」(XsltTransformer.setSource())。

在情況1(unmarshalDocumentToObject())我有一個文件路徑進來的,所以我可以只是改變transformDocument()採取文件路徑字符串並將它傳遞,因此它可以手動進入XSLT參數。這將適用於XML和純文本。

在情況2(marshalObjectToDocument())我沒有文件路徑。我有一個對象,它被轉換成一個包含它的XML表示的巨大String。我無法將文件路徑字符串傳遞給transformDocument(),因爲我沒有文件。現在我不能使用transformDocument()。代碼重用性被破壞。

我在這一切中的目標都是能夠以某種方式在代碼中以同樣的方式處理XML和純文本文檔,並且能夠重新使用我的代碼來應用XSLT和XSD,無論我是編組或解組。這是一個quixotic目標嗎?我註定要爲每種文檔類型和方向編寫不同的代碼嗎?或者有人可以看到解決辦法嗎?

回答

1

當然,這是軟件工程的標準和基礎性的一點?這裏有三位代碼:一個應用程序,它想要運行一個轉換;執行轉換的XSLT引擎和提供對XSLT引擎提供的服務的抽象的接口層,通常將功能子集化爲僅提供應用程序需要的功能,並以更簡單的形式進行。界面層的優勢在於它降低了轉換API的複雜性;缺點是它也降低了功能。當您的應用程序開始需要更多先前隱藏的功能時,您有多種選擇:您可以向界面層添加功能(最終達到停止增加值的位置),或者您可以繞過界面層應用程序中沒有任何價值的部分。

重複使用代碼取決於識別可用於多個位置的功能。如果你的應用程序的不同位執行不同的事情,那麼它們就很難重用代碼。什麼是新的?