承包商为我的客户创建了一个相当复杂的XSLT。它在各种转换测试工具中运行良好,使用我们应用程序中的真实数据。但是Nokogiri在改造期间对它进行了解决。设置$ VERBOSE和$ DEBUG后,我仍然无法获得信息:
Exception `RuntimeError' at nokogiri/XsltStylesheet.java:231 - java.lang.NullPointerException
所以我想我会创建一个带有一些调试代码的自定义Nokogiri Gem,在我的Gemfile中使用它:
gem 'nokogiri', :git => 'ssh://git@192.168.185.65:7999/bssc/nokogiri.git'
由于版本问题,我无法理解如何解决这个问题:
Source does not contain any versions of 'nokogiri java'
所以在这一点上,我想我会伸出援手让社区有更好的想法。我确信Nokogiri对样式表中的内容并不满意,但由于XSLT的复杂性,很难找到它。
连连呢?
答案 0 :(得分:2)
...使用Nokogiri完成了一些Java原生扩展(1.7 / 1.8中的性能/清理更新)
这取决于你是否有指向合理位置的痕迹,如果没有显示你可能需要自己构建宝石的宝贵见解,请尝试jruby -Xbacktrace.style=raw ...
(这里只有一个rake任务确保你在JRuby下做这件事。)
您不能将Bundler与:git
一起使用,因为.gemspec是根据Ruby平台生成的,因此您需要构建并手动gem install
(调整版本并使用Bundler进行设置,以便您知道你正在使用哪一个。
答案 1 :(得分:0)
我不确定这是最好的方法,但是在我的RVM环境中编辑源代码,然后是最小化的build_all,允许我删除异常处理。我修改过的XsltStylesheet.java:
@JRubyMethod
public IRubyObject serialize(ThreadContext context, IRubyObject doc) throws IOException, TransformerException {
XmlDocument xmlDoc = (XmlDocument) doc;
TransformerImpl transformer = (TransformerImpl) this.sheet.newTransformer();
ByteArrayOutputStream writer = new ByteArrayOutputStream();
StreamResult streamResult = new StreamResult(writer);
SerializationHandler serializationHandler = transformer.createSerializationHandler(streamResult);
serializationHandler.serialize(xmlDoc.getNode());
return context.getRuntime().newString(writer.toString());
}
@JRubyMethod(rest = true, required=1, optional=2)
public IRubyObject transform(ThreadContext context, IRubyObject[] args) throws TransformerException, IOException {
Ruby runtime = context.getRuntime();
System.out.println("in transform");
argumentTypeCheck(runtime, args[0]);
System.out.println("before listener");
// NokogiriXsltErrorListener elistener = new NokogiriXsltErrorListener();
System.out.println("before dom");
DOMSource domSource = new DOMSource(((XmlDocument) args[0]).getDocument());
final DOMResult result; String stringResult = null;
System.out.println("try transform");
result = tryXsltTransformation(context, args, domSource, null); // DOMResult
if (stringResult == null) {
return createDocumentFromDomResult(context, runtime, result);
} else {
return createDocumentFromString(context, runtime, stringResult);
}
}
private DOMResult tryXsltTransformation(ThreadContext context, IRubyObject[] args, DOMSource domSource, NokogiriXsltErrorListener elistener) throws TransformerException {
Transformer transf = sheet.newTransformer();
transf.reset();
// transf.setErrorListener(elistener);
if (args.length > 1) {
addParametersToTransformer(context, transf, args[1]);
}
DOMResult result = new DOMResult();
transf.transform(domSource, result);
return result;
}
这是我的build-all脚本:
#! /usr/bin/env bash
#
# script to build gems for all relevant platforms:
# - MRI et al (standard gem)
# - windows (x86-mingw32 and x64-mingw32)
# - jruby
#
# Load RVM into a shell session *as a function*
if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
source "$HOME/.rvm/scripts/rvm"
elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
source "/usr/local/rvm/scripts/rvm"
else
echo "ERROR: An RVM installation was not found.\n"
fi
set -o errexit
rm -rf tmp pkg
bundle exec rake clean clobber
# holding pen
rm -rf gems
mkdir -p gems
# windows
# MRI
# jruby
bundle exec rake clean clobber
bundle exec rake generate
gem install bundler --conservative
bundle install --quiet --local || bundle install
bundle exec rake gem
cp -v pkg/nokogiri*java.gem gems
这产生了输出:
...
try transform
file:///Users/jeff/Documents/BlueSageSource/plus/dummy.xsl; Line #0; Column #0; org.apache.xpath.objects.XRTreeFrag cannot be cast to org.apache.xpath.objects.XNodeSet
file:///Users/jeff/Documents/BlueSageSource/plus/dummy.xsl; Line #0; Column #0; java.lang.NullPointerException
'无法投出'消息让我得到了其他信息,表明Nokogiri不支持XSLT 2.这是令人失望的,不是因为限制,而是因为它没有很好地记录,并且使用空指针异常失败充其量是不友好的。我认为我们有足够的信息来创建一个最小的失败案例,作为增强请求提交。
参考: