[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.
|