Oga adapter
Purpose
The Oga adapter provides pure Ruby XML processing with full XPath 1.0 support, making it ideal for environments where C extensions are not allowed or desired.
Overview
Oga is a pure Ruby XML parser that requires no C extensions. It’s perfect for JRuby, TruffleRuby, Opal, or any environment where native extensions are problematic.
Configuration
# Explicit selection
context = Moxml.new
context.config.adapter = :oga
# Global default
Moxml::Config.default_adapter = :ogaFeatures
Full XPath 1.0 support
Pure Ruby implementation of XPath 1.0:
doc = Moxml.new.parse(xml)
# All XPath features work
books = doc.xpath('//book[@price < 30]')
count = doc.xpath('count(//book)')
titles = doc.xpath('//book[position() < 3]/title')
# Namespace-aware queries
doc.xpath('//ns:element', 'ns' => 'http://example.org')
# Functions and predicates
doc.xpath('//book[contains(title, "Ruby")]')Complete namespace support
Full namespace handling in pure Ruby:
# Create namespaced elements
element.add_namespace('dc', 'http://purl.org/dc/elements/1.1/')
# Query with namespaces
results = doc.xpath('//dc:creator',
'dc' => 'http://purl.org/dc/elements/1.1/')Limitations
Minor limitations compared to native implementations:
-
Slower parsing than C-based libraries
-
Higher memory usage than Ox
-
Some advanced XPath 1.0 functions may have edge case differences
| Oga’s pure Ruby implementation makes it slower than C-based libraries, but it provides excellent functionality and is faster than REXML. |
Performance characteristics
Based on benchmarks:
| Operation | Performance | Notes |
|---|---|---|
Parse medium XML | ~30-50 ips | Pure Ruby parsing |
Serialize medium XML | ~2,000+ ips | Efficient serialization |
XPath queries | ~20,000+ ips | Pure Ruby XPath engine |
Memory usage | Medium | More than C libraries, less than REXML |
Best use cases
Choose Oga when:
-
Pure Ruby environment is required (JRuby, TruffleRuby)
-
C extensions cannot be compiled or used
-
Browser deployment via Opal is needed
-
Full XPath 1.0 support is required without C dependencies
-
Easier debugging of XML processing is desired
Avoid Oga when:
Example usage
Basic document processing
require 'moxml'
# Configure Oga adapter
context = Moxml.new
context.config.adapter = :oga
xml = <<~XML
<library>
<book id="1">
<title>Ruby Programming</title>
<price>29.99</price>
</book>
</library>
XML
doc = context.parse(xml)
# Query with XPath
book = doc.at_xpath('//book[@id="1"]')
puts book.at_xpath('.//title').text # => "Ruby Programming"
# Modify
book.at_xpath('.//price').text = '24.99'
# Serialize
puts doc.to_xml(indent: 2)XPath queries
# Complex XPath expressions work
cheap_books = doc.xpath('//book[price < 25]')
fiction = doc.xpath('//book[@category="fiction"]')
last_book = doc.at_xpath('//book[last()]')
# Functions
book_count = doc.xpath('count(//book)')
has_isbn = doc.xpath('//book[string-length(@isbn) = 13]')Namespace handling
xml = <<~XML
<library xmlns:dc="http://purl.org/dc/elements/1.1/">
<book>
<dc:title>Programming</dc:title>
<dc:creator>Smith</dc:creator>
</book>
</library>
XML
doc = Moxml.new.parse(xml)
# Query with namespaces
ns = { 'dc' => 'http://purl.org/dc/elements/1.1/' }
titles = doc.xpath('//dc:title', ns)
puts titles.first.text # => "Programming"JRuby and TruffleRuby support
Oga is particularly valuable for alternative Ruby implementations:
# Works identically on JRuby
# jruby -S gem install moxml oga
# jruby script.rb
# Works on TruffleRuby
# Same code, no modifications needed
require 'moxml'
context = Moxml.new
context.config.adapter = :oga
# Full functionality on all Ruby implementations
doc = context.parse(xml)
results = doc.xpath('//book[@id="1"]')Comparison with other pure Ruby options
| Aspect | Oga | REXML |
|---|---|---|
XPath support | Full XPath 1.0 | Limited |
Performance | Fast for pure Ruby | Medium |
Memory usage | Medium | Medium |
Namespace XPath | Full support | Not supported |
Standard library | No (external gem) | Yes (built-in) |
Maintenance | Active | Active |
See also
-
Compatibility matrix - Feature comparison
-
REXML adapter - Alternative pure Ruby option