2014-01-08 144 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

这是正确的..出于某种原因,我想关闭函数只在整个过程结束时被调用,我没有注意到它的论点..现在我已经安排了代码,它的工作很好, 谢谢! –