2012-06-01 61 views
0

我知道我可以將參數從Java傳遞到xsl轉換中,但是如何在變換完成後讀取變量/參數?從Java中讀取xsl轉換變量

例如,我有一個這樣的XML文檔:

<author> 
    <name>Barry Bonds</name> 
    <books> 
    <book>Hitting Home Runs</book> 
    <book>Cheating at Baseball</book> 
    <book>Nobody Likes Cooperstown Anyway</book> 
    <books> 
<author> 

在一個單一的變換,我希望能夠轉換的名稱元素,並存儲爲一個變量,也變換書元素並將它們存儲爲第二個變量。然後,我想在轉換後從Java代碼中訪問這兩個變量。

這是可能的,如果是這樣,它是如何完成的?

感謝Michael Kay的回答,我現在有了一個解決方案。對於其他人誰遇到這一點,這裏的顯示單元測試它是如何工作:

import net.sf.saxon.*; 
import org.junit.Test; 

import javax.xml.transform.Result; 
import javax.xml.transform.Source; 
import javax.xml.transform.TransformerException; 
import javax.xml.transform.stream.StreamResult; 
import java.io.ByteArrayOutputStream; 
import java.io.UnsupportedEncodingException; 
import java.util.HashMap; 
import java.util.Map; 

import static org.junit.Assert.assertEquals; 

public class SimpleTransform { 
    @Test 
    public void splitOutput() throws TransformerException, UnsupportedEncodingException { 
     final Map<String, StreamResult> results = new HashMap<String, StreamResult>(); 
     results.put("test1", new StreamResult(new ByteArrayOutputStream())); 
     results.put("test2", new StreamResult(new ByteArrayOutputStream())); 
     results.put("test3", new StreamResult(new ByteArrayOutputStream())); 

     TransformerFactoryImpl factory = new TransformerFactoryImpl(); 
     Source source = new StandardURIResolver(new Configuration()).resolve("transform.xslt", null); 
     Controller xsl = (Controller) factory.newTransformer(source); 
     xsl.setOutputURIResolver(new OutputURIResolver() { 
      @Override 
      public Result resolve(String s, String s1) throws TransformerException { 
       return results.get(s); 
      } 

      @Override 
      public void close(Result result) throws TransformerException { 
      } 
     }); 
     Source xsd = (Source) Transform.loadDocuments("input.xml", false, null, false); 
     StreamResult standardResult = new StreamResult(new ByteArrayOutputStream()); 
     xsl.transform(xsd, standardResult); 

     for (Map.Entry<String, StreamResult> stringStreamResultEntry : results.entrySet()) { 
      System.out.println(stringStreamResultEntry.getKey() + ": " + ((ByteArrayOutputStream)stringStreamResultEntry.getValue().getOutputStream()).toString("UTF-8")); 
     } 

     assertEquals("<html>\n <body>test1</body>\n</html>", ((ByteArrayOutputStream) results.get("test1").getOutputStream()).toString("UTF-8")); 
     assertEquals("<html>\n <body>test2</body>\n</html>", ((ByteArrayOutputStream) results.get("test2").getOutputStream()).toString("UTF-8")); 
     assertEquals("<html>\n <body>test3</body>\n</html>", ((ByteArrayOutputStream) results.get("test3").getOutputStream()).toString("UTF-8")); 
    } 
} 
+0

那麼您使用的是哪種不同的Java XSLT處理器?你希望變換的結果是你想要的變量中的哪種數據類型?使用XSLT 2.0,當然可以通過一次轉換來創建多個結果序列,並且根據XSLT 2.0處理器的API,您肯定能夠將結果序列存儲在變量中,但我們並不清楚您的描述是否有幫助。 –

+0

目前我正在使用Java 6(Tr​​ansformerFactory.newInstance()。newTransformer())附帶的轉換器。儘管如此,我願意接受更好的建議。我正在尋找的輸出大多隻是多個字符串,所以聽起來好像可以做到,也許我只是缺少api中的某些東西,或者需要一個更有特色的變壓器。 – user605331

+0

...添加到我的最新評論。對於任何建議的變壓器,寧願開源選項。 – user605331

回答

2

切換到XSLT 2.0(實際上你的情況,這意味着撒克遜人),並使用XSL生成每個輸出:結果文檔的指令。您可以通過向Saxon註冊OutputURIResolver將結果文檔交付給您的Java應用程序 - 這是一個簡單的類,在創建每個結果文檔時都會收到通知。

+1

感謝您的幫助。我現在就開始工作,並編輯了原始問題,爲其他人添加示例解決方案。 – user605331