处理Saxon Parser的自定义URI解析器中的流

时间:2014-01-08 17:42:09

标签: function xslt external saxon

我必须使用创建了许多xml的结果文档对xslt处理xml。 正如这里建议的: Catch output stream of xsl result-document

我写了我的个人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)如果在多线程进程中调用此函数怎么办? (我对Saxon解析不是很熟练,所以我真的不知道..)

3)是否有可能为每个解析创建和处理一个FileOutputStream?

1 个答案:

答案 0 :(得分: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) {}
}

从Saxon-EE 9.5开始,xsl:result-document在一个新线程中执行,因此OutputURIResolver应该是线程安全的非常重要。由于这种变化,从9.5开始,OutputURIResolver必须实现一个额外的方法getInstance(),这样可以更容易地管理状态:如果你的newInstance()方法实际上创建了一个新实例,那么每个结果文档都会有一个OutputURIResolver实例正在处理,它可以保存输出流并在请求时关闭它。