| Java: Write DTD Valid XHTML |
| Sunday, 16 October 2011 22:45 |
|
Here's an example of how to write a DTD validated XHTML file from Java. Notes:
import java.io.ByteArrayInputStream;
import java.io.FileWriter;
import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class MyMain {
public static void main(String[] args) {
try {
//
// 1.) Write XML as DOM Document
//
String filename = "./src/junk.xhtml";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
factory.setNamespaceAware(false);
DocumentBuilder builder = factory.newDocumentBuilder();
Document myXML = builder.newDocument();
Element html = myXML.createElement("html");
myXML.appendChild(html);
Element head = myXML.createElement("head");
html.appendChild(head);
Element title = myXML.createElement("title");
title.setTextContent("My Homepage");
head.appendChild(title);
Element body = myXML.createElement("body");
html.appendChild(body);
//
// 2.) Write DOM Document to string
//
DOMSource domSource = new DOMSource(myXML);
TransformerFactory transformFactory = TransformerFactory
.newInstance();
StringWriter out = new StringWriter();
Transformer tf = transformFactory.newTransformer();
tf.setOutputProperty(OutputKeys.INDENT, "yes");
tf.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,
"-//W3C//DTD XHTML 1.0 Strict//EN");
// Note: Point DOCTYPE_SYSTEM at the local file system. Accessing the
// www.w3.org DTD seems to frequently time outs etc.
tf.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,".//DTD//xhtml1-strict.dtd");
tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
tf.setOutputProperty(OutputKeys.VERSION, "1.0");
tf.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
tf.setOutputProperty(OutputKeys.METHOD, "xml");
tf.transform(domSource, new StreamResult(out));
//
// 3.) Validate the XML File that was just written
//
ByteArrayInputStream string2Input = new ByteArrayInputStream(out
.toString().getBytes());
XHTMLErrorHandler xhtmlErrors = new XHTMLErrorHandler();
builder.setErrorHandler(xhtmlErrors);
builder.parse(string2Input);
if (xhtmlErrors.getProblemCount() != 0) {
return;
}
//
// 4.) Write the XML File to disc
//
FileWriter fileout = new FileWriter(filename);
tf.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd");
tf.transform(domSource, new StreamResult(fileout));
System.out.println("Successfully generated '"+filename+"'");
} catch (Exception e) {
e.printStackTrace();
}
}
}
XHTMLErrorHandler.java
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public class XHTMLErrorHandler implements ErrorHandler {
private int problemCount;
public XHTMLErrorHandler() {
problemCount = 0;
}
public int getProblemCount() {
return problemCount;
}
@Override
public void error(SAXParseException exception) throws SAXException {
problemCount += 1;
System.out.println("*** Error (line:" + exception.getLineNumber()
+ ", column:" + exception.getColumnNumber() + "): "
+ exception.getMessage());
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
problemCount += 1;
System.out.println("*** Fatal Error (line:" + exception.getLineNumber()
+ ", column:" + exception.getColumnNumber() + "): "
+ exception.getMessage());
}
@Override
public void warning(SAXParseException exception) throws SAXException {
problemCount += 1;
System.out.println("Warning (line:" + exception.getLineNumber()
+ ", column:" + exception.getColumnNumber() + "): "
+ exception.getMessage());
}
};
|