旧版Saxon9:XSL调用Java Runtime Exec无法获取脚本返回值
在Saxon9中执行Ruby脚本并获取返回结果的实现方案
你的需求完全可以在Saxon9中实现。当前代码仅输出进程对象标识,是因为你直接输出了java.lang.Process对象的toString()结果,而非脚本的实际输出内容。要获取脚本返回结果,需要读取进程的标准输出流。
问题分析
原代码仅完成了启动进程并等待执行结束的操作,但没有读取进程输出流:
<xsl:variable name="javatest" select="runtime:exec(runtime:getRuntime(), 'ruby test.rb')" /> <xsl:variable name="waiting" select = "process:waitFor($javatest)" /> <xsl:value-of select="$javatest" />
直接输出$javatest只会得到进程对象的内存地址标识,而非脚本输出。
解决方案
通过Java的IO类读取进程的标准输出流,以下是修改后的完整代码示例:
首先在XSL样式表根节点绑定必要的Java类命名空间:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:runtime="java:java.lang.Runtime" xmlns:process="java:java.lang.Process" xmlns:inputstream="java:java.io.InputStream" xmlns:bufferedreader="java:java.io.BufferedReader" xmlns:inputstreamreader="java:java.io.InputStreamReader" xmlns:string="java:java.lang.String">
然后添加执行脚本并读取输出的逻辑:
<xsl:template match="/"> <!-- 启动Ruby脚本进程 --> <xsl:variable name="javatest" select="runtime:exec(runtime:getRuntime(), 'ruby test.rb')" /> <!-- 等待进程执行结束并获取退出码 --> <xsl:variable name="exit-code" select="process:waitFor($javatest)" /> <!-- 读取脚本标准输出流 --> <xsl:variable name="input-stream" select="process:getInputStream($javatest)" /> <xsl:variable name="reader" select="bufferedreader:new(inputstreamreader:new($input-stream))" /> <xsl:variable name="script-output"> <xsl:call-template name="read-stream"> <xsl:with-param name="reader" select="$reader" /> </xsl:call-template> </xsl:variable> <!-- 输出执行结果 --> <xsl:text>脚本执行退出码:</xsl:text> <xsl:value-of select="$exit-code" /> <xsl:text> 脚本输出内容: </xsl:text> <xsl:value-of select="$script-output" /> <!-- 关闭流和销毁进程,避免资源泄漏 --> <xsl:value-of select="bufferedreader:close($reader)" /> <xsl:value-of select="process:destroy($javatest)" /> </xsl:template> <!-- 递归读取流内容的模板 --> <xsl:template name="read-stream"> <xsl:param name="reader" /> <xsl:variable name="line" select="bufferedreader:readLine($reader)" /> <xsl:if test="not(string:isEmpty($line))"> <xsl:value-of select="$line" /> <xsl:text> </xsl:text> <xsl:call-template name="read-stream"> <xsl:with-param name="reader" select="$reader" /> </xsl:call-template> </xsl:if> </xsl:template>
关键注意事项
- 如果脚本输出到标准错误流(stderr),需要替换为
process:getErrorStream($javatest)读取 - 确保执行环境中能找到
ruby命令,建议使用绝对路径(如/usr/bin/ruby test.rb)避免路径问题 - 通过
$exit-code可以判断脚本执行是否成功(0为成功,非0为异常) - 必须关闭流和销毁进程,避免资源泄漏
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

