Setting DOCTYPE to a DOM- document

M

Michael Preminger

Hello!

I am trying to create an XHTML-document using the org.w3c.dom and
javax.xml.transform package, but cannot find
any elegant way of putting a <DOCTYPE declaration into the output document.

I create a Document object with the newDocument() method of a
javax.xml.parsers.DocumentBuilder object, and writing it out using an
identity transform, (as in sun's tutorial
http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JAXPXSLT4.html)

The turorial has a recommendation for processing DOCTYPE, using the
following code:
....
if (document.getDoctype() != null){
String systemValue = (new
File(document.getDoctype().getSystemId())).getName();
transformer.setOutputProperty(
OutputKeys.DOCTYPE_SYSTEM, systemValue
);
}

But this does not seem to have the effect I expect, and is probably not
intended for my expressed need.


Is there a standard way of setting a
<DOCTYPE ...> declaration to a DOM - document created in this way, or do
I have to create my XHTML some other way?


Thanks

Michael
 
J

John C. Bollinger

Michael said:
I am trying to create an XHTML-document using the org.w3c.dom and
javax.xml.transform package, but cannot find
any elegant way of putting a <DOCTYPE declaration into the output document.

I create a Document object with the newDocument() method of a
javax.xml.parsers.DocumentBuilder object, and writing it out using an
identity transform, (as in sun's tutorial
http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JAXPXSLT4.html)

You cannot set a DocumentType on an existing Document, but you should be
able to create a Document that has the desired type in the first place.
Get a DOMImplementation object from your DocumentBuilder -- it has the
methods you need.
The turorial has a recommendation for processing DOCTYPE, using the
following code:
...
if (document.getDoctype() != null){
String systemValue = (new
File(document.getDoctype().getSystemId())).getName();
transformer.setOutputProperty(
OutputKeys.DOCTYPE_SYSTEM, systemValue
);
}

Not immediately relevant. That's for _processing_ the DocumentType for
a Document when it has one; it is not useful in assigning a DocumentType
to a Document instance that doesn't already have one. You may find it
needful after you get a Document containing DocumentType node, but you
may find that you don't need it at all.
But this does not seem to have the effect I expect, and is probably not
intended for my expressed need.


Is there a standard way of setting a
<DOCTYPE ...> declaration to a DOM - document created in this way, or do
I have to create my XHTML some other way?

See above.


John Bollinger
(e-mail address removed)
 
M

Michael Preminger

Thanks alot! Sorry to bother you with it, but

I found the following possibility : (Is this what you were pointing to?)

DocumentType
newDocType=builder.getDOMImplementation().createDocumentType(
"html",
"-//W3C//DTD XHTML 1.1//EN",
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"
);

newDoc = builder.getDOMImplementation().createDocument(
"http://www.w3.org/1999/xhtml",
"html",
newDocType);

Which at the first attempt in fact seemed to work, but when I reordered
the code, putting things into methods a.s.o I seem to have lost it.

The above procedure now produces the following:
<?xml version="1.0" encoding="UTF-8"?>
<html><head>

No Doctype.

I cant for my lifetime figure out what Im doing wrong!!

Thanks
 
J

John C. Bollinger

Michael Preminger wrote:

Please do not top-post.
Thanks alot! Sorry to bother you with it, but

I found the following possibility : (Is this what you were pointing to?)

DocumentType
newDocType=builder.getDOMImplementation().createDocumentType(
"html",
"-//W3C//DTD XHTML 1.1//EN",
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"
);

newDoc = builder.getDOMImplementation().createDocument(
"http://www.w3.org/1999/xhtml",
"html",
newDocType);

Yes, that is what I had in mind.
Which at the first attempt in fact seemed to work, but when I reordered
the code, putting things into methods a.s.o I seem to have lost it.

"Seems to work" as judged how? You were able to produce the desired
output from a Document obtained in that manner? Or did you check it
some other way? If the code worked before your refactoring but not
after, then it follows that the refactoring was not performed correctly.
The above procedure now produces the following:
<?xml version="1.0" encoding="UTF-8"?>
<html><head>

No it doesn't. The above procedure produces a reference to a Document
object. The relationship between that object and the text you have
shown is at best unclear.
I cant for my lifetime figure out what Im doing wrong!!

I have little chance of figuring out what you're doing wrong if I can't
figure out what you're doing. If you want further assistance then you
will considerably aid your cause by preparing and posting a small,
self-contained, compilable example that demonstrates the problem.


John Bollinger
(e-mail address removed)
 
J

John C. Bollinger

All,

Resolution:

The method described earlier in this thread for creating a Document with
DocumentType works as expected. However, that is not enough to achieve
the OP's goal. (In fact, it may be orthogonal to that goal.) The OP
was using a default Transformer to output a representation of his DOM
document, and even though the document had a correct document type node,
it was not reflected in the output. This appears to be because the data
model used by XSLT does not accommodate document type declarations, and
hence a Transformer object (or any other XSLT transformation mechanism)
will not emit one without coaxing. One could write an appropriate
document type declaration into the stylesheet as text, but that
precludes using a default Transformer. There is a more flexible way:

[...]

import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;

[...]

/**
* Applies an identity XSLT transform to the provided DOM Document,
* directing the result to provided Result object. If the document
* contains a DocumentType node then its public and system ids are
* provided as the appropriate properties of the transform, which
* will generally cause a DOCTYPE declaration to be part of the
* transformation result (but whether or not the provided Result
* object does anything with it depends on that object).
*
* @param doc the DOM Document to copy
* @param result the Result object that should receive the
* copy
*
* @throws TransformerException if one occurs while obtaining an
* Transformer instance or while performing the
* transformation
*/
public void transformWithDoctype(Document doc, Result result)
throws TransformerException {
TransformerFactory factory = TransformerFactory.newInstance();
Transformer xformer = factory.newTransformer();
DocumentType doctype = doc.getDoctype();

if (doctype != null) {
xformer.setOutputProperty(
OutputKeys.DOCTYPE_PUBLIC,
doctype.getPublicId());
xformer.setOutputProperty(
OutputKeys.DOCTYPE_SYSTEM,
doctype.getSystemId());
}

/*
* Note: the default output method is used (either "xml" or
* "html", depending on the document). See chapter 16 of the
* XSLT spec for the details.
*/

xformer.transform(new DOMSource(doc), result);
}

[...]

This should also be expressible directly in XSLT.


John Bollinger
(e-mail address removed)
 
J

John C. Bollinger

Michael:

I wrote a response to your e-mail, but your mail system does not appear
to be accepting it from mine. Refer to my last response on this thread
for information on resolving your problem.

John Bollinger
(e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top