[Practicalxml-commits] SF.net SVN: practicalxml:[31] trunk/src
Brought to you by:
kdgregory
From: Auto-Generated S. C. M. <pra...@li...> - 2008-10-12 16:57:17
|
Revision: 31 http://practicalxml.svn.sourceforge.net/practicalxml/?rev=31&view=rev Author: kdgregory Date: 2008-10-12 16:57:10 +0000 (Sun, 12 Oct 2008) Log Message: ----------- ParseUtil: add schema validation Modified Paths: -------------- trunk/src/main/java/net/sf/practicalxml/ParseUtil.java trunk/src/test/java/net/sf/practicalxml/TestParseUtil.java Modified: trunk/src/main/java/net/sf/practicalxml/ParseUtil.java =================================================================== --- trunk/src/main/java/net/sf/practicalxml/ParseUtil.java 2008-10-12 13:05:05 UTC (rev 30) +++ trunk/src/main/java/net/sf/practicalxml/ParseUtil.java 2008-10-12 16:57:10 UTC (rev 31) @@ -6,6 +6,7 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import javax.xml.validation.Schema; import net.sf.practicalxml.misc.ExceptionErrorHandler; @@ -119,10 +120,40 @@ public static Document validatingParse( InputSource source, ErrorHandler errHandler) { - return validatingParse(source, null, errHandler); + return validatingParse(source, (EntityResolver)null, errHandler); } + /** + * Parses the supplied source with a namespace-aware, XSD-validating + * parser, using a caller-supplied error handler and entity resolver. + * Both of these objects may be <code>null</code>, to use the built-in + * defaults. + * + * @throws XmlException for any configuration or fatal execution error. + */ + public static Document validatingParse( + InputSource source, Schema schema, ErrorHandler errHandler) + { + DocumentBuilder db = newXSDDocumentBuilder(schema); + if (errHandler != null) + db.setErrorHandler(errHandler); + + try + { + return db.parse(source); + } + catch (IOException e) + { + throw new XmlException("unable to parse", e); + } + catch (SAXException e) + { + throw new XmlException("unable to parse", e); + } + } + + //---------------------------------------------------------------------------- // Internals //---------------------------------------------------------------------------- @@ -134,6 +165,9 @@ private static DocumentBuilderFactory _dtdDbf; + /** + * Returns a namespace-aware, non-validating parser. + */ private static synchronized DocumentBuilder newNVDocumentBuilder() { if (_nvDbf == null) @@ -155,6 +189,9 @@ } + /** + * Returns a namespace-aware, DTD-validating parser. + */ private static synchronized DocumentBuilder newDTDDocumentBuilder() { if (_dtdDbf == null) @@ -174,4 +211,28 @@ throw new XmlException("unable to confiure parser", e); } } + + + /** + * Returns a namespace-aware, XSD-validating parser using the supplied + * schema. Note that we don't use a singleton factory, because the schema + * gets applied to the factory, not the parser. + */ + private static synchronized DocumentBuilder newXSDDocumentBuilder(Schema schema) + { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setValidating(false); + dbf.setCoalescing(true); + dbf.setSchema(schema); + + try + { + return _dtdDbf.newDocumentBuilder(); + } + catch (ParserConfigurationException e) + { + throw new XmlException("unable to confiure parser", e); + } + } } Modified: trunk/src/test/java/net/sf/practicalxml/TestParseUtil.java =================================================================== --- trunk/src/test/java/net/sf/practicalxml/TestParseUtil.java 2008-10-12 13:05:05 UTC (rev 30) +++ trunk/src/test/java/net/sf/practicalxml/TestParseUtil.java 2008-10-12 16:57:10 UTC (rev 31) @@ -5,6 +5,11 @@ import java.util.ArrayList; import java.util.List; +import javax.xml.XMLConstants; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; + import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Text; @@ -30,7 +35,43 @@ + "<!ATTLIST foo name CDATA #REQUIRED>"; + /** An XSD that replicates the DTD above */ + private final static String BASIC_XSD + = "<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" + + "<xsd:element name=\"foo\" type=\"FooType\"/>" + + "<xsd:complexType name=\"FooType\">" + + "<xsd:sequence>" + + "<xsd:element name=\"bar\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>" + + "<xsd:element name=\"baz\" minOccurs=\"1\" maxOccurs=\"unbounded\">" + + "<xsd:complexType>" + + "</xsd:complexType>" + + "</xsd:element>" + + "</xsd:sequence>" + + "<xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>" + + "</xsd:complexType>" + + "</xsd:schema>"; + + /** + * Creates a <code>Schema</code> object from source XML. We could use + * {@link SchemaUtil}, but I'd like this test to be as self-contained + * as possible. + */ + private static Schema createSchema(String xsd) + { + try + { + SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + return sf.newSchema(new StreamSource(new StringReader(xsd))); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + + + /** * An ErrorHandler that records its invocations, and provides asserts * on them. */ @@ -63,38 +104,8 @@ assertEquals("TestErrorHandler warnings", numWarnings, warnings.size()); } } - - - /** - * An EntityResolver that will resolve a single entity. - */ - private static class TestEntityResolver - implements EntityResolver - { - private String _publicId; - private String _systemId; - private String _content; - - public TestEntityResolver(String publicId, String systemId, String content) - { - _publicId = publicId; - _systemId = systemId; - _content = content; - } - public InputSource resolveEntity(String publicId, String systemId) - throws SAXException, IOException - { - if (((publicId == null) || publicId.equals(_publicId)) - && ((systemId == null) || systemId.equals(_systemId))) - { - return new InputSource(new StringReader(_content)); - } - return null; - } - } - //---------------------------------------------------------------------------- // Test Cases //---------------------------------------------------------------------------- @@ -229,13 +240,40 @@ + "<baz/>" + "</foo>"; + EntityResolver resolver = new EntityResolver() + { + public InputSource resolveEntity(String publicId, String systemId) + throws SAXException, IOException + { + return new InputSource(new StringReader(BASIC_DTD)); + } + }; TestErrorHandler errHandler = new TestErrorHandler(); - TestEntityResolver resolver = new TestEntityResolver(null, "test", BASIC_DTD); Document doc = ParseUtil.validatingParse( new InputSource(new StringReader(xml)), - resolver, errHandler); + resolver, + errHandler); assertEquals("foo", doc.getDocumentElement().getTagName()); errHandler.assertResults(0, 0, 0); } + + + public void testValidDocumentWithSchema() throws Exception + { + String xml + = "<foo name='zippy'>" + + "<bar>something here</bar>" + + "<baz/>" + + "</foo>"; + + TestErrorHandler errHandler = new TestErrorHandler(); + Document doc = ParseUtil.validatingParse( + new InputSource(new StringReader(xml)), + createSchema(BASIC_XSD), + errHandler); + + assertEquals("foo", doc.getDocumentElement().getTagName()); + errHandler.assertResults(0, 0, 0); + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |