views:

972

answers:

1

I see in my application that xinclude inside my parsed XML file does not work within my Java XSLT conversion.

However, although I do:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setXIncludeAware(true);

I'm not specifically setting the transformer factory as System.getProperty("javax.xml.transform.TransformerFactory") returns "null".

My question: does the default Java (1.6 or 6) support xinclude or do I have to add an alternative XSLT parser such as Apache Xerces?

+3  A: 

According to the spec, support has been there since Java 1.5 (5). I believe XInclude support relies on namespace awareness, which is turned off by default for backwards compatibility reasons.

public class XIncludeDemo {

    private static final String XML = "<?xml version=\"1.0\"?>\n"
      + "<data xmlns=\"foo\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"&gt;\n"
      + "<xi:include href=\"include.txt\" parse=\"text\"/>\n"
      + "</data>\n";

    private static final String INCLUDE = "Hello, World!";

    public static void main(String[] args) throws Exception {
     // data
     final InputStream xmlStream = new ByteArrayInputStream(XML
       .getBytes("UTF-8"));
     final InputStream includeStream = new ByteArrayInputStream(INCLUDE
       .getBytes("UTF-8"));
     // document parser
     DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
     factory.setXIncludeAware(true);
     factory.setNamespaceAware(true);
     DocumentBuilder docBuilder = factory.newDocumentBuilder();
     if (!docBuilder.isXIncludeAware()) {
      throw new IllegalStateException();
     }
     docBuilder.setEntityResolver(new EntityResolver() {
      @Override
      public InputSource resolveEntity(String publicId, String systemId)
        throws SAXException, IOException {
       if (systemId.endsWith("include.txt")) {
        return new InputSource(includeStream);
       }
       return null;
      }
     });
     Document doc = docBuilder.parse(xmlStream);
     // print result
     Source source = new DOMSource(doc);
     Result result = new StreamResult(System.out);
     TransformerFactory transformerFactory = TransformerFactory
       .newInstance();
     Transformer transformer = transformerFactory.newTransformer();
     transformer.transform(source, result);
    }

}
McDowell
Thank you for the information. I will need some time to apply it and see if I can accept it. The information you gave me is however what I needed.
Roalt
Thanks, just what I was looking for!
Tyler Egeto