I've this JRuby working code (stolen from Keith's Blog), which wraps the SAXON xslt processor API.
Now, I wonder whether I can and how can I wrap the same API in Ruby framework?
Please tell me if this question is non-sense or if it can be improved in some way.
This is the java doc reference for the wanted API.
And this is the JRuby code I'm using:
require 'java'
module JXslt
include_class "javax.xml.transform.TransformerFactory"
include_class "javax.xml.transform.Transformer"
include_class "javax.xml.transform.stream.StreamSource"
include_class "javax.xml.transform.stream.StreamResult"
include_class "java.lang.System"
class XsltProcessor
def transform(xslt,infile,outfile)
transformer = @tf.newTransformer(StreamSource.new(xslt))
transformer.transform(Strea开发者_如何学GomSource.new(infile), StreamResult.new(outfile))
end
end # XsltProcessor
class Saxon < XsltProcessor
TRANSFORMER_FACTORY_IMPL = "net.sf.saxon.TransformerFactoryImpl"
def initialize
System.setProperty("javax.xml.transform.TransformerFactory", TRANSFORMER_FACTORY_IMPL)
@tf = TransformerFactory.newInstance
end
end
end
As commented above, you can not do this directly from the Ruby runtime, calling Java from Ruby requires you to be either on JRuby or call Java indirectly using the C/C++ JVM API that allows you to call Java code from C.
The first option is possibly using Ruby Java Bridge that does most of the heavy lifting for you (it functions as a Ruby-to-C-to-Java wrapper).
If RJB doesn't work for you, you can also build your wrapper directly by using the JVM API in C ( example here ) and then you could call it from Ruby using FFI.
But unless you really need to use the C-Ruby (MRI) I would greatly recommend you to avoid any of the approaches above and just use JRuby, as delving into native code will lead to possible segfaults, memory management issues and all options above force you to run in a single thread, while you could build a multi-threaded solution by using JRuby.
精彩评论