Document Purpose: Clarify XPath requirements and Saxon's role in XBRL processing
Last Updated: January 2026
Target Audience: XBRL processor developers
The Reality:
For a production-grade XBRL processor that handles all XBRL specifications (especially Formula), you need XPath 2.0+, and Saxon (by Saxonica, Oxford UK) is essentially the only viable choice for Java implementations.
While technically other options exist, in practice:
| XBRL Specification | XPath Version | Required? | Alternatives Viable? |
|---|---|---|---|
| XBRL 2.1 Core | XPath 1.0 (minimal) | No* | Yes |
| Dimensions 1.0 | XPath 1.0 (minimal) | No* | Yes |
| Inline XBRL | None | No | N/A |
| xBRL-JSON | None | No | N/A |
| xBRL-CSV | None | No | N/A |
| Calculations 2.0 | None | No | N/A |
| Formula 1.0 | XPath 2.0 | YES | No - Saxon only |
| Table Linkbase | XPath 2.0 | YES** | No - Saxon only |
| Extensible Enumerations | None | No | N/A |
| Versioning | None | No | N/A |
* Some edge cases use XPath but can be worked around
** Table Linkbase uses Formula infrastructure
If you want to support Formula (business rules validation):
XBRL Formula specification requires XPath 2.0, which added:
if-then-else expressionsfor and let expressionsXPath 1.0 Cannot Handle Formula - The specification fundamentally requires XPath 2.0 features.
XBRL Formula Processors (Production Use):
├─ Arelle (Python) → Uses Saxon via Py4J
├─ Altova Tools → Uses Saxon
├─ Fujitsu XWand → Uses Saxon
├─ UBmatrix Processor → Uses Saxon
├─ GLOMIDCO 2014-2016 Processor → Uses Saxon
└─ 99% of other processors → Use Saxon
XPath 2.0+ Processors for Java:
| Processor | Status | XBRL Viability |
|---|---|---|
| Saxon | ✅ Active, mature | ✅ Production ready |
| Apache Xalan | XPath 1.0 only | ❌ Cannot do Formula |
| BaseX | XQuery focus | ⚠️ Theoretically possible, not tested with XBRL |
| eXist-db | Database focus | ⚠️ Not designed for this |
| Jaxen | XPath 1.0 only | ❌ Cannot do Formula |
The Reality:
XBRL International doesn't mandate specific implementations, but:
License: Open Source (Mozilla Public License 2.0)
Cost: FREE
XPath Support: XPath 2.0, XQuery 1.0, XSLT 2.0
Capabilities for XBRL:
Verdict: Sufficient for basic Formula, FREE
License: Commercial
Cost: ~€500-2000/year (varies)
XPath Support: XPath 3.0, XQuery 3.0, XSLT 3.0
Additional Capabilities:
Verdict: Better for production, moderate cost
License: Commercial
Cost: ~€2000-10000/year (varies)
XPath Support: XPath 3.1, XQuery 3.1, XSLT 3.0
Additional Capabilities:
Verdict: Enterprise-grade, expensive
Your Needs → Recommended Edition
Basic Formula validation → Saxon HE (FREE)
Production processor, moderate scale → Saxon PE
Enterprise processor, high volume → Saxon EE
Open source/hobby project → Saxon HE (FREE)
Commercial product → Saxon PE or EE
<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId>
<version>12.4</version> <!-- Latest as of 2024 -->
</dependency>
import net.sf.saxon.s9api.*;
public class XBRLFormulaProcessor {
private Processor processor;
private XPathCompiler xpathCompiler;
public XBRLFormulaProcessor() {
// Initialize Saxon
processor = new Processor(false); // false = HE edition
xpathCompiler = processor.newXPathCompiler();
// Declare XBRL namespaces
xpathCompiler.declareNamespace("xbrl",
"http://www.xbrl.org/2003/instance");
xpathCompiler.declareNamespace("xfi",
"http://www.xbrl.org/2005/xbrlfi");
}
public boolean evaluateAssertion(String xpathExpr,
XdmNode contextNode)
throws SaxonApiException {
XPathSelector selector = xpathCompiler.compile(xpathExpr)
.load();
selector.setContextItem(contextNode);
XdmValue result = selector.evaluate();
return result.itemAt(0).getBooleanValue();
}
// Formula variable binding
public void bindVariable(String name, XdmValue value) {
xpathCompiler.declareVariable(new QName(name));
}
// Custom function registration
public void registerCustomFunction(String namespace,
String name,
ExtensionFunction function) {
processor.registerExtensionFunction(
new ExtensionFunctionDefinition() {
// Implementation details...
}
);
}
}
// 1. Load instance as Saxon XdmNode
DocumentBuilder builder = processor.newDocumentBuilder();
XdmNode instanceDoc = builder.build(new File("instance.xbrl"));
// 2. Select facts using XPath
XPathSelector factSelector = xpathCompiler
.compile("//ex:Revenue[@contextRef='c1']")
.load();
factSelector.setContextItem(instanceDoc);
XdmValue revenueFacts = factSelector.evaluate();
// 3. Evaluate assertion
XPathExecutable assertion = xpathCompiler
.compile("$revenue gt 0");
XPathSelector assertionSelector = assertion.load();
assertionSelector.setVariable(new QName("revenue"), revenueFacts);
boolean passes = assertionSelector.evaluateSingle()
.getBooleanValue();
Effort Required:
Estimated Development:
Verdict: ❌ Not economically viable
BaseX (XQuery processor):
Estimated adaptation effort: 6-12 months testing + fixes
If you skip Formula support:
Use cases that require Formula:
Verdict: For a complete processor, you need Formula, therefore you need Saxon.
Name: Saxonica Limited
Location: Oxford, United Kingdom
Founded: 2004
Founder: Dr. Michael Kay (also author of Saxon)
Size: Small company (~10-20 people)
Status: Active, ongoing development
Single Point of Dependency:
Current Status (2026):
Include:
Requirements:
Rationale:
Include:
Requirements:
Rationale:
Core processor (no Saxon):
Optional Formula module (with Saxon):
Rationale:
Mozilla Public License 2.0:
For Your Processor:
License Requirements:
Cost Models:
For Your Processor:
Dependency Risk:
Your processor depends on Saxonica continuing Saxon development.
Mitigation Strategies:
Use Saxon HE (open source)
Abstract XPath layer
Monitor alternatives
Consider XPath 3.1 features carefully
Current (2026):
Future Possibilities:
Reality Check:
None of these exist yet for production XBRL use.
Even though you'll use Saxon, design with abstraction:
// Your abstraction
public interface XPathProcessor {
Object evaluate(String expression, Object context);
void registerFunction(String name, Function impl);
void declareVariable(String name, Object value);
}
// Saxon implementation
public class SaxonXPathProcessor implements XPathProcessor {
private Processor processor;
// Saxon-specific implementation
}
// Future alternative (if it ever exists)
public class AlternativeXPathProcessor implements XPathProcessor {
// Different implementation
}
Benefits:
Reality:
Costs:
Limitations:
Costs:
Benefits:
Costs:
When Worth It:
| Feature | Saxon | BaseX (alternative) | Custom Build |
|---|---|---|---|
| XPath 2.0 | ✅ Complete | ✅ Yes | ⚠️ Years of work |
| XPath 3.1 | ✅ (EE) | ✅ Yes | ❌ No |
| Java API | ✅ Excellent | ✅ Good | ✅ Your design |
| XBRL Testing | ✅ Extensive | ❌ None | ❌ Years needed |
| Performance | ✅ Optimized | ✅ Good | ⚠️ Unknown |
| Memory Use | ✅ Efficient | ⚠️ Higher | ⚠️ Unknown |
| Community | ✅ Large | ⚠️ Small (XQuery) | ❌ None |
| Support | ✅ Commercial | ⚠️ Community | ❌ Self |
| XBRL Functions | ✅ Tested | ❌ Untested | ❌ Must implement |
| Conformance | ✅ 100% | ⚠️ Unknown | ❌ Uncertain |
Verdict: Saxon is the only proven option
The Pattern:
Formula spec was written knowing Saxon would be the implementation. Not officially, but pragmatically.
Arelle (Python - most popular open source):
# Uses Saxon via Py4J bridge
from py4j.java_gateway import JavaGateway
gateway = JavaGateway()
saxon = gateway.entry_point.getSaxonProcessor()
Altova (Commercial):
Major Accounting Firms' Tools:
Regulators' Validation:
Your Situation:
You're in good company. Everyone uses Saxon.
For a complete XBRL processor supporting all specifications:
Your 2014-2018 processor likely already uses Saxon. Check your dependencies:
<!-- Look for this in your pom.xml or build files -->
<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>saxon</artifactId>
<!-- or Saxon-HE, Saxon-PE, Saxon-EE -->
</dependency>
If you're already using Saxon:
If you want to avoid Saxon:
Saxon/Saxonica is effectively a required dependency for comprehensive XBRL processing.
This is:
Recommendation: Use Saxon HE (free) or PE (commercial support), abstract your XPath layer for good design, and move forward confidently knowing you're using the same foundation as every other serious XBRL processor.
This document reflects the practical reality of XBRL processor development as of January 2026. While technically XPath is an open W3C standard with multiple implementations, Saxon is the de facto standard for production XBRL Formula processing.