A
Andrew Thompson
This example* shows how to validate XML against XSD.
What I would *like* to do is also offer validation
against DTD. Unforutnately, when the 'DTD' XMLConstant
is selected in the last dialog (bottom option
http://www.w3.org/TR/REC-xml), I get the output..
"Create schema from 'http://java.sun.com/dtd/JNLP-1.5.dtd'.
Exception in thread "main" java.lang.IllegalArgumentException:
No SchemaFactory that implements the schema language specified by:
http://www.w3.org/TR/REC-xml could be loaded
at javax.xml.validation.SchemaFactory
.newInstance(SchemaFactory.java:207)
..."
Does anybody demonstrate how to validate against DTD?
BTW - A quick search on ..
<http://www.google.com/search?q=XML_DTD_NS_URI+"No+SchemaFactory">
..did not reveal 'much', so I am thinking I
have 'got this all wrong'.
*
<sscce>
import java.io.IOException;
import javax.swing.JOptionPane;
import javax.swing.JComboBox;
import javax.xml.XMLConstants;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Schema;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.stream.StreamSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
import org.w3c.dom.Document;
/** Simple example of validating a structured document (XML)
against a schema (XSD).
Can anybody change this to code that will successfully
validate against a DTD? */
class XMLValidate {
public static void main(String[] args) throws
ParserConfigurationException,
SAXException,
IOException
{
String[] contentOptions =
{
// The Player JNLP is meant to pop the Java Control Panel
// It was never intended to be valid accoring to the spec.,
// as such, it is a good 'target' for validation, as it will
// most likely remain 'invalid' according to the DTD/XSD
"http://java.sun.com/products/javawebstart/apps/player.jnlp"
,
// Sun's Java2D Demo - valid at time of check
"http://java.sun.com/products/jfc/jws/Java2Demo.jnlp"
,
// example of loading file from same directory
"file:./xmlv.jnlp"
};
String content = null;
String[] definitionOptions =
{
// the XSD from the PhySci site
"http://www.physci.org/JNLP-6.0.xsd"
,
// DTD for the Sun JNLP format
// **can we create a schema from this?**
"http://java.sun.com/dtd/JNLP-1.5.dtd"
,
// for access from local file-system
"file:../373XMLValidator/xmlvalidate/build/dist/JNLP-6.0.xsd"
};
String definition = null;
String[] languageOptions =
{
// XML
XMLConstants.W3C_XML_SCHEMA_NS_URI
,
//
XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI
,
// RelaxNG
XMLConstants.RELAXNG_NS_URI
,
// XPath
XMLConstants.W3C_XPATH_DATATYPE_NS_URI
,
// DTD
// No SchemaFactory that implements the schema language ..
XMLConstants.XML_DTD_NS_URI
};
String language = null;
XMLErrorHandler errorHandler = new XMLErrorHandler();
if (args.length==2) {
content = args[0];
definition = args[1];
} else if (args.length==0) {
JComboBox contentChoice = new JComboBox (contentOptions);
contentChoice.setEditable(true);
JOptionPane.showMessageDialog(
null,
contentChoice,
"XML URL (document)",
JOptionPane.QUESTION_MESSAGE
);
content = (String)contentChoice.getSelectedItem();
JComboBox definitionChoice = new JComboBox (definitionOptions);
definitionChoice.setEditable(true);
JOptionPane.showMessageDialog(
null,
definitionChoice,
"XSD(/DTD) URL (schema definition)",
JOptionPane.QUESTION_MESSAGE
);
definition = (String)definitionChoice.getSelectedItem();
JComboBox languageChoice = new JComboBox (languageOptions);
languageChoice.setEditable(true);
JOptionPane.showMessageDialog(
null,
languageChoice,
"Language - see XMLConstants",
JOptionPane.QUESTION_MESSAGE
);
language = (String)languageChoice.getSelectedItem();
} else {
System.out.println(
"Usage: java XMLValidate "+
"file:./the.xml file:./the.xsd XMLConstants.languages");
System.out.println(
"Usage: java XMLValidate (will prompt for params)");
}
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
factory.setFeature("http://xml.org/sax/features/validation", true);
factory.setFeature("http://apache.org/xml/features/validation/schema",
true) ;
factory.setAttribute(
"
http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation",
definition);
System.out.println("Create schema from '" + definition + "'.");
SchemaFactory schemaFactory = SchemaFactory.newInstance(language);
Schema schema = schemaFactory.newSchema( new StreamSource(definition) );
factory.setSchema( schema );
System.out.println("Schema created successfully.");
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
documentBuilder.setErrorHandler( errorHandler );
System.out.println("Validate content from '" +
content +
"' against schema.");
try {
Document document = documentBuilder.parse( content );
} catch (SAXException e) {
System.err.println( e.getMessage() );
System.err.println( "Validation failed.." );
}
System.out.println(
"Total (warning, error, fatal) errors detected: " +
errorHandler.getErrorCount() );
}
}
class XMLErrorHandler extends DefaultHandler {
private int errorCount=0;
public void warning(SAXParseException exception)
throws SAXException {
processException(exception);
}
public void error(SAXParseException exception)
throws SAXException {
processException(exception);
}
public void fatalError(SAXParseException exception)
throws SAXException {
processException(exception);
}
public void processException(SAXParseException exception) {
System.err.println(exception);
errorCount++;
}
public int getErrorCount() {
return errorCount;
}
}
</sscce>
What I would *like* to do is also offer validation
against DTD. Unforutnately, when the 'DTD' XMLConstant
is selected in the last dialog (bottom option
http://www.w3.org/TR/REC-xml), I get the output..
"Create schema from 'http://java.sun.com/dtd/JNLP-1.5.dtd'.
Exception in thread "main" java.lang.IllegalArgumentException:
No SchemaFactory that implements the schema language specified by:
http://www.w3.org/TR/REC-xml could be loaded
at javax.xml.validation.SchemaFactory
.newInstance(SchemaFactory.java:207)
..."
Does anybody demonstrate how to validate against DTD?
BTW - A quick search on ..
<http://www.google.com/search?q=XML_DTD_NS_URI+"No+SchemaFactory">
..did not reveal 'much', so I am thinking I
have 'got this all wrong'.
*
<sscce>
import java.io.IOException;
import javax.swing.JOptionPane;
import javax.swing.JComboBox;
import javax.xml.XMLConstants;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Schema;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.stream.StreamSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
import org.w3c.dom.Document;
/** Simple example of validating a structured document (XML)
against a schema (XSD).
Can anybody change this to code that will successfully
validate against a DTD? */
class XMLValidate {
public static void main(String[] args) throws
ParserConfigurationException,
SAXException,
IOException
{
String[] contentOptions =
{
// The Player JNLP is meant to pop the Java Control Panel
// It was never intended to be valid accoring to the spec.,
// as such, it is a good 'target' for validation, as it will
// most likely remain 'invalid' according to the DTD/XSD
"http://java.sun.com/products/javawebstart/apps/player.jnlp"
,
// Sun's Java2D Demo - valid at time of check
"http://java.sun.com/products/jfc/jws/Java2Demo.jnlp"
,
// example of loading file from same directory
"file:./xmlv.jnlp"
};
String content = null;
String[] definitionOptions =
{
// the XSD from the PhySci site
"http://www.physci.org/JNLP-6.0.xsd"
,
// DTD for the Sun JNLP format
// **can we create a schema from this?**
"http://java.sun.com/dtd/JNLP-1.5.dtd"
,
// for access from local file-system
"file:../373XMLValidator/xmlvalidate/build/dist/JNLP-6.0.xsd"
};
String definition = null;
String[] languageOptions =
{
// XML
XMLConstants.W3C_XML_SCHEMA_NS_URI
,
//
XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI
,
// RelaxNG
XMLConstants.RELAXNG_NS_URI
,
// XPath
XMLConstants.W3C_XPATH_DATATYPE_NS_URI
,
// DTD
// No SchemaFactory that implements the schema language ..
XMLConstants.XML_DTD_NS_URI
};
String language = null;
XMLErrorHandler errorHandler = new XMLErrorHandler();
if (args.length==2) {
content = args[0];
definition = args[1];
} else if (args.length==0) {
JComboBox contentChoice = new JComboBox (contentOptions);
contentChoice.setEditable(true);
JOptionPane.showMessageDialog(
null,
contentChoice,
"XML URL (document)",
JOptionPane.QUESTION_MESSAGE
);
content = (String)contentChoice.getSelectedItem();
JComboBox definitionChoice = new JComboBox (definitionOptions);
definitionChoice.setEditable(true);
JOptionPane.showMessageDialog(
null,
definitionChoice,
"XSD(/DTD) URL (schema definition)",
JOptionPane.QUESTION_MESSAGE
);
definition = (String)definitionChoice.getSelectedItem();
JComboBox languageChoice = new JComboBox (languageOptions);
languageChoice.setEditable(true);
JOptionPane.showMessageDialog(
null,
languageChoice,
"Language - see XMLConstants",
JOptionPane.QUESTION_MESSAGE
);
language = (String)languageChoice.getSelectedItem();
} else {
System.out.println(
"Usage: java XMLValidate "+
"file:./the.xml file:./the.xsd XMLConstants.languages");
System.out.println(
"Usage: java XMLValidate (will prompt for params)");
}
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
factory.setFeature("http://xml.org/sax/features/validation", true);
factory.setFeature("http://apache.org/xml/features/validation/schema",
true) ;
factory.setAttribute(
"
http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation",
definition);
System.out.println("Create schema from '" + definition + "'.");
SchemaFactory schemaFactory = SchemaFactory.newInstance(language);
Schema schema = schemaFactory.newSchema( new StreamSource(definition) );
factory.setSchema( schema );
System.out.println("Schema created successfully.");
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
documentBuilder.setErrorHandler( errorHandler );
System.out.println("Validate content from '" +
content +
"' against schema.");
try {
Document document = documentBuilder.parse( content );
} catch (SAXException e) {
System.err.println( e.getMessage() );
System.err.println( "Validation failed.." );
}
System.out.println(
"Total (warning, error, fatal) errors detected: " +
errorHandler.getErrorCount() );
}
}
class XMLErrorHandler extends DefaultHandler {
private int errorCount=0;
public void warning(SAXParseException exception)
throws SAXException {
processException(exception);
}
public void error(SAXParseException exception)
throws SAXException {
processException(exception);
}
public void fatalError(SAXParseException exception)
throws SAXException {
processException(exception);
}
public void processException(SAXParseException exception) {
System.err.println(exception);
errorCount++;
}
public int getErrorCount() {
return errorCount;
}
}
</sscce>