Skip to content

Pure Java Nokogiri for JRuby

yokolet edited this page Sep 12, 2010 · 18 revisions

What is “pure Java” Nokogiri?

Pure Java version of Nokogiri is a Java port for JRuby. Currently, FFI version of Nokogiri works on JRuby via FFI library, and it needs libxml2 installed. On the other hand, pure Java version doesn’t use libxml2 and FFI library. Nokogiri’s libxml2 dependent methods have been implemented by Apache Xerces, nekoHTML, and a couple of more pure Java APIs. This means we don’t have limitation to use Nokogiri even on a pure Java environment. Yes, Nokogiri is available on Google App Engine.

How to build

Since pure Java version of Nokogiri is not yet finished, there is no downloadable archive so far. You need to clone the source and build it. Charlie wrote a nice, easy-to follow blog entry,
Nokogiri Java Port: Help Us Finish It!
, which will help you, definitely.

Quick start

To use pure Java Nokogiri, lib/nokogiri/nokogiri.jar and lib/*.jar should be in your classpath and lib/nokogiri should be in your load path. Or, you may choose to install the gem to your JRuby. For example, after you could build pure Java Nokogiri successfully, you can install the gem as in below:

jruby -S rake java:gem
jruby -S gem install path-to-nokogiri-home/pkg/nokogiri-1.4.0.20100415101221-java.gem
Successfully installed nokogiri-1.4.0.20100415101221-java
1 gem installed
Installing ri documentation for nokogiri-1.4.0.20100415101221-java...(snip)

Make sure your JRuby has pure Java Nokogiri.

$ jruby -S gem list

		
  • LOCAL GEMS *
    hoe (2.6.0)
    jruby-openssl (0.6)
    json_pure (1.2.4)
    nokogiri (1.4.0.20100415101221)
    rake (0.8.7)
    rubyforge (2.0.4)
    sources (0.0.1)

Let’s try a simple example.

$ jruby -S irb
irb(main):001:0> require ‘rubygems’
=> true
irb(main):002:0> require ‘nokogiri’
=> true
irb(main):003:0> doc = Nokogiri::XML “<root><foo /><quux /></root>”
=> #<Nokogiri::XML::Document:0×7e4 name=“document” children=[#<Nokogiri::XML::Element:0×7e2 name=“root” children=[#<Nokogiri::XML::Element:0×7de name="foo">, #<Nokogiri::XML::Element:0×7e0 name="quux">]>]>
irb(main):004:0> doc.to_xml
=> “<?xml version=\”1.0\“?>\n<root>\n <foo/><quux/>\n</root>\n\n”
irb(main):005:0> node = doc.at_css(“foo”)
=> #<Nokogiri::XML::Element:0×7de name="foo">
irb(main):006:0> node.next_element
=> #<Nokogiri::XML::Element:0×7e6 name="quux">
irb(main):007:0>

Pure Java Specific Rules

Porting to Java is not easy. Contributors have struggled over the different behaviors between libxml2 and Xerces. Almost all Nokogiri API are implemented as they are, but some were very hard to make. Thus, pure Java version has a few specific rules. Please be aware followings when you use pure Java version.

DTD validation

Add “dtdvalid” option when a document is read.

xml = Nokogiri::XML(File.open(XML_FILE)) {|cfg| cfg.dtdvalid}
list = xml.internal_subset.validate xml

The number of errors is not the same as libxml2 version. Java version doesn’t report errors of attributes whose elements have already reported errors.

Public ID in DOCTYPE declaration

Don’t forget to write the second parameter.

<!DOCTYPE foo PUBLIC “bar” "">