2014-01-08 186 views
0

我必須針對xslt處理xml,並在結果文檔中創建許多xml。 由於這裏建議: Catch output stream of xsl result-document在自定義URI解析器中處理Saxon解析器的流解析器

,我寫我的個人URI解析器:

public class CustomOutputURIResolver implements OutputURIResolver{ 

    private File directoryOut; 

    public CustomOutputURIResolver(File directoryOut) { 
     super(); 
     this.directoryOut = directoryOut; 
    } 

    public void close(Result arg0) throws TransformerException { 

    } 

    public Result resolve(String href, String base) throws TransformerException { 
     FileOutputStream fout = null; 
     try { 
      File f = new File(directoryOut.getAbsolutePath() + File.separator + href + File.separator + href + ".xml"); 
      f.getParentFile().mkdirs(); 
      fout = new FileOutputStream(f); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } 
     return new StreamResult(fout); 
    } 

} 

該得到的輸出目錄,然後在這裏保存文件。

但是當我在junit中測試它時,我在清理階段出現了一些問題,當試圖刪除創建的文件時,發現FileOutputStream fout處理不好。 試圖解決這個問題給了我一些想法:

首先,我想出了這樣的想法:

public class CustomOutputURIResolver implements OutputURIResolver{ 

    private File directoryOut; 
    private FileOutputStream fout 

    public CustomOutputURIResolver(File directoryOut) { 
     super(); 
     this.directoryOut = directoryOut; 
     this.fout = null; 
    } 

    public void close(Result arg0) throws TransformerException { 
     try { 
      if (null != fout) { 
       fout.flush(); 
       fout.close(); 
       fout = null; 
      } 
     } catch (Exception e) {} 
    } 

    public Result resolve(String href, String base) throws TransformerException { 

     try { 
      if (null != fout) { 
       fout.flush(); 
       fout.close(); 
      } 
     } catch (Exception e) {} 

     fout = null; 
     try { 
      File f = new File(directoryOut.getAbsolutePath() + File.separator + href + File.separator + href + ".xml"); 
     f.getParentFile().mkdirs(); 
      fout = new FileOutputStream(f); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } 
     return new StreamResult(fout); 
    } 

} 

所以FileOutputStream中被關閉隨時另一個被打開。 但是:

1)我不喜歡這種解決方案非常

2)如果調用此函數在多線程程序是什麼? (我對撒克遜語解析並不熟練,所以我真的不知道..)

3)是否有機會爲每個解決方案創建並處理一個FileOutputStream?

回答

1

close()接受Result參數的原因是,您可以確定要關閉哪個流。爲什麼不:

public void close(Result arg0) throws TransformerException { 
    try { 
     if (arg0 instanceof StreamResult) { 
      OutputStream os = ((StreamResult)arg0).getOutputStream(); 
      os.flush(); 
      os.close(); 
     } 
    } catch (Exception e) {} 
} 

從撒克遜EE 9.5,XSL:結果文檔在一個新的線程執行,所以這是非常重要的OutputURIResolver應該是線程安全的。由於這種變化,從9.5開始,OutputURIResolver必須實現一個額外的方法getInstance(),這使得它更容易管理狀態:如果newInstance()方法實際創建一個新實例,那麼每個結果文檔將有一個OutputURIResolver實例正在處理,它可以保存輸出流並在請求時關閉它。

+0

這是正確的..出於某種原因,我想關閉函數只在整個過程結束時被調用,我沒有注意到它的論點..現在我已經安排了代碼,它的工作很好, 謝謝! –