Search code examples
javaxmlxsltxalanxinclude

java xalan transform with and without xinclude in the same app


I write a book database application in java. The books stored in XML format. Every book a XML. The books can contains short stories and a short story can be a XML. In that case the book look like:

<?xml version="1.0" encoding="UTF-8"?>
...
<book>
  <content>
    <xi:include  xmlns:xi="http://www.w3.org/2001/XInclude" href="shortStory.xml"/>
  </content>
</book>

Because the user can upload only one xml, and it can be the "book.xml" wihtout the "shortStory.xml" (the shortStory.xml always uploaded before) I need to do the XSLT Transform without xinclude. (et case the two file is not the same path)

But after the upload (in other usecase) I need to do the XSLT transform with the XInclude (the two file is the same path)

Every solution what use the Xinclude set the System Property before get a instance from Transformerfactory:

System.setProperty(
    "org.apache.xerces.xni.parser.XMLParserConfiguration",
    "org.apache.xerces.parsers.XIncludeParserConfiguration"); 

Or use DocumentBuilderFactory.setXIncludeAware().

I'd like two javax.xml.transform.Transformer one set up use the xinclude and one without. Or one transformert but a simple method for javax.xml.transform.stream.StreamSource to turn on/ot the xinclude.

thanx

EDIT

Try out Martin Honnen's solution, but there was problem with the transform, so I change the SAXreader to Documentbuilder:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setXIncludeAware(true);
DocumentBuilder docBuilder = factory.newDocumentBuilder();
Document doc = docBuilder.parse(input);
Source source = new DOMSource(doc);
...
transformer.transform(source, result);

Solution

  • I think that is more a question related to the XML parser than to the XSLT processor. According to http://xerces.apache.org/xerces2-j/features.html you can set

    import javax.xml.parsers.SAXParser;
    import org.xml.sax.SAXException;
    import org.xml.sax.XMLReader;
    
    SAXParser parser = /* created from SAXParserFactory */;
    XMLReader reader = parser.getXMLReader();
    try {
        reader.setFeature("http://apache.org/xml/features/xinclude", 
                          true);
    } 
    catch (SAXException e) {
        System.err.println("could not set parser feature");
    }
    

    Then you can build a SAXSource with that reader I think:

    SAXSource source = new SAXSource();
    source.setXMLReader(reader);
    

    that way you have a way to build a source with XInclude turned on or off, without needing to set a system property.