Skip to Content.
Sympa Menu

xom-interest - [XOM-interest] xi:include and xml:base in XSLT

xom-interest AT lists.ibiblio.org

Subject: XOM API for Processing XML with Java

List archive

Chronological Thread  
  • From: Axel von Engel <a.vonengel AT gmail.com>
  • To: xom-interest AT lists.ibiblio.org
  • Subject: [XOM-interest] xi:include and xml:base in XSLT
  • Date: Fri, 3 May 2019 21:44:11 +0200

Hi everyone,

(This got a bit long, see last paragraph for TL;DR)

I recently started to work on migrating a DocBook toolchain to a Gradle
plugin, and was looking into doing all the transformations via SAX in Java.
The pre-existing toolchain at the company uses a variety of pre- and
post-processing XSL stylesheets, and even used different processors for
those.

My first approach was the following:
1. Parse the source via Xerces
2. Construct a TransformerHandler backed by Saxon for each of the
stylesheets
3. Use a FOP renderer as the final SAX ContentHandler to create PDF output

This worked pretty well, until I ran into this lovely Xerces issue:
https://issues.apache.org/jira/browse/XERCESJ-1102
So basically, nested xi:include tags result in wrong xml:base attributes,
leading to wrong relative image paths.

Through some searching, I found XOM, and used that on top of Xerces:

SAXParserFactory parserFactory =
SAXParserFactory.newInstance("org.apache.xerces.jaxp.SAXParserFactoryImpl",
classloader);
// disable xInclude on the Xerces parser
parserFactory.setXIncludeAware(false);
// more config ...
XMLReader xmlReader = parserFactory.newSAXParser().getXMLReader();

Builder parser = new Builder(xmlReader);
Document input = parser.build(rootDocbookFile);

input = XIncluder.resolve(input, parser);

// handler creation omitted:
SAXConverter saxConverter = new SAXConverter(handler);
saxConverter.convert(input);

The problem with this approach: the SAXConverter does not emit xml:base
attributes. I later found this in the sources:
https://github.com/elharo/xom/blob/master/src/nu/xom/converters/SAXConverter.java#L98
Which led to my current workaround hack: Use reflection to set
SAXConverter.stripBaseAttributes = true

Another approach I tried was to use XOM to do the XSL transformations
instead of using the SAX API. This resulted in some errors that said
something like "can't insert Text into Document" without any meaningful
hints at which XSL template might have caused it, so I didn't investigate
further.

All in all, I feel this is a hack, and find it hard to believe there is no
cleaner solution. Google and Stackoverflow didn't turn up much else, though.

TL;DR: My root issue is with Xerces: it can't properly resolve nested
xi:include tags.
Does someone know another solution to parse the XML, and resolve the
xi:include tags correctly?
Is there some way to debug what causes XOM to error during XSLT?
Or maybe there is another way to get the results from XOM to the SAX API
(including xml:base attributes, and without writing to disk)?

Best regards
Axel von Engel




Archive powered by MHonArc 2.6.24.

Top of Page