Skip to main content

Missing DTD from output

5 replies [Last post]
minka99
Offline
Joined: 2008-03-27
Points: 0

Is this a bug or am I doing something wrong?
The input xml has a DTD, as does the DOM, but the output after the transform()
does not.
Thanks!

String xmlDT = "<?xml version=\"1.0\" encoding=\"utf-8\"?> ]> Oberon's Legacy Corets, Eva 5.95 ";

ByteArrayInputStream xml = new ByteArrayInputStream(xmlDT.getBytes());
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document node = builder.parse(xml);
TransformerFactory xformFactory = TransformerFactory.newInstance();
Transformer idTransform = xformFactory.newTransformer();
Source input = new DOMSource(node);
ByteArrayOutputStream xml2 = new ByteArrayOutputStream();
Result output = new StreamResult(xml2);
idTransform.transform(input, output);
xml2.close();
System.out.println( xml2.toString()); // DTD is missing from xml

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
joehw
Offline
Joined: 2004-12-15
Points: 0

I think you need a stylesheet that contains DOCTYPE declaration.

minka99
Offline
Joined: 2008-03-27
Points: 0

This from the javadoc:

If all that is desired is the simple identity transformation of a source to a result, then TransformerFactory provides a TransformerFactory.newTransformer() method with no arguments. This method creates a Transformer that effectively copies the source to the result. This method may be used to create a DOM from SAX events or to create an XML or HTML stream from a DOM or SAX events.

This is what I'm using above. So it seems to be that the effective copy should
include the DTD. Not including it would be an exception to the identity transform, but no exceptions are documented.

joehw
Offline
Joined: 2004-12-15
Points: 0

XSLT uses a data model similar to XPath. Check out the XSLT spec. -> Output (http://www.w3.org/TR/xslt#output) In order to include Doctype delarations, a stylesheet containing DOCTYPE declaration is needed.

minka99
Offline
Joined: 2008-03-27
Points: 0

I looked into this, see below. The template I am using copies all sources nodes to the output.
It does not copy the dtd. There is still no dtd in the output.
This reference says there is no way to write a stylesheet that copies an internal dtd to
the output: http://markmail.org/message/wj7zz34whcvq3zn7

If there is a way, I'd appreciate a tip, thanks!

package javaTest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.w3c.dom.Document;

public class JavaTest1 {

public static void main(String[] args) throws Exception {

String xmlDT = "
]> y\" ISBN=\"2-3631-4\"> Oberon's Legacy Corets, Eva
5.95
";
ByteArrayInputStream xml = new ByteArrayInputStream(xmlDT.getBytes());
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document node = builder.parse(xml);
Source style = null;
if (node.getDoctype() != null) {
// build stylesheet
String stylesheet = "";
stylesheet += " stylesheet += node.getDoctype().getNodeName() + " [";
stylesheet += node.getDoctype().getInternalSubset();
stylesheet += " ]>" ;
stylesheet += "";
stylesheet += "";
stylesheet += "";
stylesheet += "";
stylesheet += "";
stylesheet += "
";
stylesheet += "
";
stylesheet += "
";
ByteArrayInputStream xsl = new ByteArrayInputStream(stylesheet.getBytes());
style = new StreamSource(xsl);
}
TransformerFactory xformFactory = TransformerFactory.newInstance();
Transformer idTransform = (style == null) ? xformFactory.newTransformer() : xformFactory.newTransformer(style);
Source input = new DOMSource(node);
ByteArrayOutputStream xml2 = new ByteArrayOutputStream();
Result output = new StreamResult(xml2);
idTransform.transform(input, output);
xml2.close();
System.out.println( xml2.toString()); // DTD is missing from xml
}
}

joehw
Offline
Joined: 2004-12-15
Points: 0

You're right. The XSLT Output element has only support for external DTD files through doctype-system and doctype-public. Unfortunately for internal DTD subsets, you'd have to construct them manually.