0

It looks like com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl is not handling CDATA properly when using a namespace.

Consider the following example:

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class CdataTest {
  public final String tmpDir = "/tmp";
  public final String nameSpace = "http://sample.namespace.com";
  public final String cdataFields = String.format("{%s}title {%s}description", nameSpace, nameSpace);

  public static void main(String[] args) {
    CdataTest test = new CdataTest();
    String fileName = String.format("%s/%s.xml", test.tmpDir, "Feed");
    String fileNameFormatted = String.format("%s/%sFormatted.xml", test.tmpDir, "Feed");
    try {
      test.transform(fileName, fileNameFormatted, test.cdataFields);
    } catch (TransformerException e) {
      e.printStackTrace();
    }
  }

  private void transform(String source, String destination, String cdataFields) throws TransformerException {
    System.out.println(cdataFields);
    TransformerFactory factory = TransformerFactory.newInstance();
    Transformer transformer = factory.newTransformer();
    transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, cdataFields);
    transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer.transform(new StreamSource(source), new StreamResult(destination));
  }
}

Using the following XML

<?xml version="1.0" encoding="UTF-8"?>
<entries xmlns="http://sample.namespace.com">
  <entry id="1">
    <title>sample title 1</title>
    <description>sample description 1</description>
  </entry>
  <entry id="2">
    <title>sample title 2</title>
    <description>sample description 2</description>
  </entry>
</entries>

Running it by explicitly specifying the TransformerFactory implementation

java -Djaxp.debug=1 -Djavax.xml.transform.TransformerFactory=com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl CdataTest

Does not properly handle CDATA fields. However if the namespace is removed from both the transformation code and XML the document is transformed correctly.

It's important to note that the above works correctly using org.apache.xalan.processor.TransformerFactoryImpl, however that's not an option...

How can I properly handle CDATA fields with a namespace using com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl?

Boyan
  • 165
  • 1
  • 2
  • 8
  • 1
    By getting the bug fixed. Which I suspect is unlikely, unless you fix it yourself. – Michael Kay Jan 15 '15 at 22:24
  • @MichaelKay isn't this a common problem? The reason I would like to use com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl is because this code runs under tomcat 7 and adding xalan.jar to the container just creates more problems. Ideas...? – Boyan Jan 16 '15 at 00:26
  • I've no idea whether it's a common problem. But being a common problem doesn't get it fixed. An even more common problem with open source software as that the people who wrote it move on to other things and lose interest in fixing bugs. Now, if you want an XSLT processor that runs under Java and has been regularly maintained for 15 years, I could suggest Saxon... – Michael Kay Jan 16 '15 at 09:25

0 Answers0