How to add DOCTYPE in XML using jaxp-1.2 ?

Hi all,

I know this question has been asked at least 2000 times. But I couldn't find the answer from the previously posted messages.

I would like to create a new Document (actually a XML document) and to write it out into a file. Of course, to be useful, that document needs a DTD... But I can't find a way to create thatDOCTYPE tag.

In fact, I get this error: org.apache.crimson.tree.DomEx: HIERARCHY_REQUEST_ERR: This node isn't allowed there.

at org.apache.crimson.tree.XmlDocument.appendChild(XmlDocument.java:661)

at ServiceManager.PlaylistDOM.createDoc(PlaylistDOM.java:99)

at ServiceManager.PlaylistDOM.load(PlaylistDOM.java:52)

at java.lang.Thread.run(Thread.java:536)

The code I have is the following:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

try{

//create a factory and configure it

DocumentBuilder builder = factory.newDocumentBuilder();

playlistDoc = builder.newDocument();

DOMImplementation impl = builder.getDOMImplementation();

DocumentType doctype = impl.createDocumentType(ROOT_EL, null,"playlist.dtd");

playlistDoc = impl.createDocument(null, ROOT_EL, doctype);

}

catch (ParserConfigurationException pce){}

//create the root of the XML file

Element root = (Element) playlistDoc.createElement(ROOT_EL);

root.setAttribute(FRAME_ATTR, fNb);

playlistDoc.appendChild(root);

//now print it out into XML file

TransformerFactory tfactory = TransformerFactory.newInstance();

try{

Transformer transformer = tfactory.newTransformer();

DOMSource source =new DOMSource(playlistDoc.getDocumentElement());

StreamResult res =new StreamResult(new File(filename));

transformer.transform(source, res);

}

catch (TransformerConfigurationException tce){}

catch (TransformerException te){}

Thank you for your help

[2675 byte] By [karau] at [2007-9-19]
# 1
The DTD is nothing more than a comment that most parsers will process. Try creating a Comment and adding it as the first node of the document. I haven't tried that, but it makes sense.
ken_robinson at 2007-7-5 > top of java,Enterprise & Remote Computing,Enterprise Technologies...
# 2

Hi Karau,

I had the same exact problem, and I just found the solution:

There is no way of setting or modifying the DOCTYPE declaration in the XML document itself; according to the documentation, this is not allowed by the DOM Level 2 specification. However, you can do it in the javax.xml.Transformer object:

...

TransformerFactory tFactory = TransformerFactory.newInstance();

Transformer transformer = tFactory.newTransformer();

transformer.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_SYSTEM, "name.dtd");

...

Check the javax.xml.transform.OutputKeys javadoc for more details about the properties you can set for the transformer.

Hope it helps

Giordano

giobiondani at 2007-7-5 > top of java,Enterprise & Remote Computing,Enterprise Technologies...
# 3
> transformer.setOutputProperty(javax.xml.transform.Outpu> Keys.DOCTYPE_SYSTEM, "name.dtd");Well, it works perfectly....Thank you very much ;-))Karau
karau at 2007-7-5 > top of java,Enterprise & Remote Computing,Enterprise Technologies...
# 4
And do you know if it is possible to add a stylesheet declaration using the Transformer ?
karau at 2007-7-5 > top of java,Enterprise & Remote Computing,Enterprise Technologies...
# 5
It seem works for SYSTEM, but don't work for PUBLIC. Anybody know why?
wkang at 2007-7-5 > top of java,Enterprise & Remote Computing,Enterprise Technologies...
# 6

add both SYSTEM and PUBLIC, then you will find PUBLIC :P

================

If the doctype-public or doctype-system attributes are specified, then the html output method should output a document type declaration immediately before the first element. The name following <!DOCTYPE should be HTML or html. If the doctype-public attribute is specified, then the output method should output PUBLIC followed by the specified public identifier; if the doctype-system attribute is also specified, it should also output the specified system identifier following the public identifier. If the doctype-system attribute is specified but the doctype-public attribute is not specified, then the output method should output SYSTEM followed by the specified system identifier.

reference: http://java.sun.com/j2se/1.4.1/docs/api/javax/xml/transform/OutputKeys.html>

tissues1 at 2007-7-5 > top of java,Enterprise & Remote Computing,Enterprise Technologies...
# 7

I tried using the Transformer to set the DOCTYPE. I just put the three lines above after creating my Document object. I then tried

System.out.println("OutputProp: " +transformer.getOutputProperty("javax.xml.transform.OutputKeys.DOCTYPE_SYSTEM"));

Nothing prints out b/c it seems like the DOCTYPE is never getting set. Am I missing something?

tommyxman1 at 2007-7-5 > top of java,Enterprise & Remote Computing,Enterprise Technologies...