Hi, I reworked my changes to the XMLValidateTask so that it looks more like the Style task from users perspective. I alos removed the use of Collection libraries.
A nice improvement would be to use the Factory element like the Style task. The tests are also updated, and run when the xerces parser is in the classpath. They will fail with crimson since it does not support schema validation, is this OK? Regards, Nick
Index: docs/manual/OptionalTasks/xmlvalidate.html =================================================================== RCS file: /home/cvspublic/jakarta-ant/docs/manual/OptionalTasks/xmlvalidate.html,v retrieving revision 1.9 diff -u -r1.9 xmlvalidate.html --- docs/manual/OptionalTasks/xmlvalidate.html 9 Sep 2002 16:49:23 -0000 1.9 +++ docs/manual/OptionalTasks/xmlvalidate.html 20 Sep 2002 09:05:29 -0000 @@ -14,9 +14,11 @@ (probably the one that is used by Ant itself), but one can specify any SAX1/2 parser if needed.</p> -<p>This task supports the use of nested <a -href="../CoreTypes/xmlcatalog.html">xmlcatalog</a> elements and/or nested -<tt><dtd></tt> elements which are used to resolve DTDs and entities.</p> +<p>This task supports the use of nested + <li/><a href="../CoreTypes/xmlcatalog.html"><tt><xmlcatalog></tt></a> elements + <li/><tt><dtd></tt> elements which are used to resolve DTDs and entities. + <li/><tt><attribute></tt> elements which are used to set features on the parser. These can be any number of <a href="http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description">http://xml.org/sax/features/</a> or other features that your parser may support. +</p> <h3>Parameters</h3> <table border="1" cellpadding="2" cellspacing="0"> @@ -84,6 +86,30 @@ <h4>xmlcatalog</h4> <p>The <a href="../CoreTypes/xmlcatalog.html">xmlcatalog</a> element is used to perform Entity resolution.</p> +<h4>attribute</h4> +<p>The attribute element is used to set SAX Parser features. +There can an arbitrary amount of attribute set as defined here: + <a href="http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description">http://xml.org/sax/features/</a> +A feature essentialy changes the mode of the parser. +<attribute> an attribute is used to set specific features on the parser. +<table border="1" cellpadding="2" cellspacing="0"> +<tr> + <td width="12%" valign="top"><b>Attribute</b></td> + <td width="78%" valign="top"><b>Description</b></td> + <td width="10%" valign="top"><b>Required</b></td> +</tr> + <tr> + <td valign="top">name</td> + <td valign="top">The name of the feature</td> + <td align="center" valign="top">Yes</td> + </tr> + <tr> + <td valign="top">value</td> + <td valign="top">The boolean value of the feature</td> + <td align="center" valign="top">Yes</td> + </tr> +</table> +</p> <h3>Examples</h3> @@ -128,8 +154,17 @@ </xmlvalidate> </pre> Scan all XML files in the project, using the catalog defined inline. -<hr> +<pre> +<xmlvalidate failonerror="yes" lenient="no" warn="yes"> + <fileset dir="xml" includes="**/*.xml"/> + <attribute name="http://xml.org/sax/features/validation" value="true"/> + <attribute name="http://apache.org/xml/features/validation/schema" value="true"/> +</xmlvalidate> +</pre> +Validate all .xml files in xml directory with the parser configured to perform schema validation. Note: The parser must support the <pre>http://apache.org/xml/features/validation/schema</pre> feature. +<br> +<hr> <p align="center">Copyright © 2001-2002 Apache Software Foundation. All rights Reserved.</p> Index: src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java =================================================================== RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java,v retrieving revision 1.25 diff -u -r1.25 XMLValidateTask.java --- src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java 9 Sep 2002 16:44:28 -0000 1.25 +++ src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java 20 Sep 2002 09:05:30 -0000 @@ -58,9 +58,8 @@ import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; -import java.util.Enumeration; -import java.util.Hashtable; import java.util.Vector; + import org.apache.tools.ant.AntClassLoader; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; @@ -89,10 +88,11 @@ * (probably the one that is used by Ant itself), but one can specify any * SAX1/2 parser if needed * @author Raphael Pierquin <a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a> + * @author Nick Pellow <a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a> */ public class XMLValidateTask extends Task { - protected static String INIT_FAILED_MSG = + protected static String INIT_FAILED_MSG = "Could not start xml validation: "; // ant task properties @@ -116,15 +116,18 @@ protected XMLReader xmlReader = null; // XMLReader used to validation process protected ValidatorErrorHandler errorHandler = new ValidatorErrorHandler(); // to report sax parsing errors - protected Hashtable features = new Hashtable(); + + /** The vector to store all attributes (features) to be set on the parser. **/ + private Vector attributeList = new Vector(); + private XMLCatalog xmlCatalog = new XMLCatalog(); /** - * Specify how parser error are to be handled. + * Specify how parser error are to be handled. * Optional, default is <code>true</code>. * <p> - * If set to <code>true</code> (default), throw a buildException if the + * If set to <code>true</code> (default), throw a buildException if the * parser yields an error. */ public void setFailOnError(boolean fail) { @@ -194,7 +197,7 @@ } /** - * Where to find the parser class; optional. + * Where to find the parser class; optional. * @see #setClasspath */ public void setClasspathRef(Reference r) { @@ -222,6 +225,19 @@ filesets.addElement(set); } + /** + * Add an attribute nested element. This is used for setting arbitrary + * features of the SAX parser. + * Valid attributes + * <a href=http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description">include</a> + * @since ant1.6 + */ + public Attribute createAttribute() { + final Attribute feature = new Attribute(); + attributeList.add(feature); + return feature; + } + public void init() throws BuildException { super.init(); xmlCatalog.setProject(getProject()); @@ -294,7 +310,7 @@ reader = JAXPUtils.getParser(); } } else { - + Class readerClass = null; try { // load the parser class @@ -318,15 +334,15 @@ // then check it implements XMLReader if (reader instanceof XMLReader) { - xmlReader = (XMLReader) reader; - log("Using SAX2 reader " + reader.getClass().getName(), + xmlReader = (XMLReader) reader; + log("Using SAX2 reader " + reader.getClass().getName(), Project.MSG_VERBOSE); } else { // see if it is a SAX1 Parser if (reader instanceof Parser) { xmlReader = new ParserAdapter((Parser) reader); - log("Using SAX1 parser " + reader.getClass().getName(), + log("Using SAX1 parser " + reader.getClass().getName(), Project.MSG_VERBOSE); } else { throw new BuildException(INIT_FAILED_MSG + readerClassName @@ -347,18 +363,23 @@ + " doesn't provide validation"); } } - // set other features - Enumeration enum = features.keys(); - while (enum.hasMoreElements()) { - String featureId = (String) enum.nextElement(); - setFeature(featureId, ((Boolean) features.get(featureId)).booleanValue(), true); + // set the feature from the attribute list + for (int i = 0; i < attributeList.size(); i++) { + Attribute feature = (Attribute) attributeList.get(i); + setFeature(feature.getName(), + feature.getValue(), + true); + } } } /** - * set a feature on the parser. - * @todo find a way to set any feature from build.xml + * Set a feature on the parser. + * @param feature the name of the feature to set + * @param value the value of the feature + * @param warn whether to war if the parser does not support the feature + */ private boolean setFeature(String feature, boolean value, boolean warn) { @@ -370,20 +391,22 @@ if (warn) { log("Could not set feature '" + feature - + "' because the parser doesn't recognize it", + + "' because the '" + + readerClassName + "' parser doesn't recognize it", Project.MSG_WARN); } } catch (SAXNotSupportedException e) { if (warn) { log("Could not set feature '" + feature - + "' because the parser doesn't support it", + + "' because the '" + + readerClassName + "' parser doesn't support it", Project.MSG_WARN); } } return toReturn; } - + /** * parse the file */ @@ -395,18 +418,18 @@ String uri = "file:" + afile.getAbsolutePath().replace('\\', '/'); for (int index = uri.indexOf('#'); index != -1; index = uri.indexOf('#')) { - uri = uri.substring(0, index) + "%23" + uri = uri.substring(0, index) + "%23" + uri.substring(index + 1); } is.setSystemId(uri); xmlReader.parse(is); } catch (SAXException ex) { if (failOnError) { - throw new BuildException("Could not validate document " + throw new BuildException("Could not validate document " + afile); } } catch (IOException ex) { - throw new BuildException("Could not validate document " + afile, + throw new BuildException("Could not validate document " + afile, ex); } @@ -480,6 +503,55 @@ } } return e.getMessage(); + } + } + + /** + * The class to create to set a feature of the parser. + * @since ant1.6 + * @author <a href="mailto:[EMAIL PROTECTED]">Nick Pellow</a> + */ + public class Attribute { + /** The name of the attribute to set. + * + * Valid attributes <a href=http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description">include.</a> + */ + private String attributeName = null; + + /** + * The value of the feature. + **/ + private boolean attributeValue; + + /** + * Set the feature name. + * @param name the name to set + */ + public void setName(String name) { + attributeName = name; + } + /** + * Set the feature value to true or false. + * @param value + */ + public void setValue(boolean value) { + attributeValue = value; + } + + /** + * Gets the attribute name. + * @return the feature name + */ + public String getName() { + return attributeName; + } + + /** + * Gets the attribute value. + * @return the featuree value + */ + public boolean getValue() { + return attributeValue; } } } Index: src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java =================================================================== RCS file: /home/cvspublic/jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java,v retrieving revision 1.3 diff -u -r1.3 XmlValidateTest.java --- src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java 1 Jun 2002 12:26:43 -0000 1.3 +++ src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java 20 Sep 2002 09:05:30 -0000 @@ -94,6 +94,7 @@ * The teardown method for JUnit */ public void tearDown() { + } @@ -124,5 +125,21 @@ */ public void testXmlCatalogNested() { executeTarget("xmlcatalognested"); + } + + /** + * Test xml schema validation + */ + public void testXmlSchemaGood() { + executeTarget("testSchemaGood"); + } + /** + * Test xml schema validation + */ + public void testXmlSchemaBad() { + expectBuildExceptionContaining( + "testSchemaBad", + "Bad Schema Validation", "not a valid XML document"); + } } Index: src/etc/testcases/taskdefs/optional/xmlvalidate.xml =================================================================== RCS file: /home/cvspublic/jakarta-ant/src/etc/testcases/taskdefs/optional/xmlvalidate.xml,v retrieving revision 1.5 diff -u -r1.5 xmlvalidate.xml --- src/etc/testcases/taskdefs/optional/xmlvalidate.xml 10 Sep 2002 16:35:01 -0000 1.5 +++ src/etc/testcases/taskdefs/optional/xmlvalidate.xml 20 Sep 2002 09:05:30 -0000 @@ -38,25 +38,29 @@ </xmlcatalog> </xmlvalidate> </target> + -<!-- <target name="testSchemaGood"> - <xmlvalidate warn="false"> - <fileset dir="xml" includes="endpiece.xml"/> - <feature name="http://xml.org/sax/features/validation" value="true"/> - <feature name="http://apache.org/xml/features/validation/schema" value="true"/> - <xmlcatalog > - <entity publicID = "nap:Massive+Attack+Mezzanine" - location = "xml/doc.xsd"/> - </xmlcatalog> + <target name="testSchemaGood"> + <xmlvalidate warn="false" lenient="no" > + <fileset dir="xml" includes="endpiece.xml"/> + + <attribute name="http://xml.org/sax/features/validation" + value="false"/> + <attribute name="http://apache.org/xml/features/validation/schema" + value="false"/> + </xmlvalidate> </target> - --> -<!-- <target name="testSchGemaBad"> + + <target name="testSchemaBad"> <xmlvalidate warn="false"> - <fileset dir="xml" includes="endpiece2.xml"/> - <feature name="http://xml.org/sax/features/validation" value="true"/> - <feature name="http://apache.org/xml/features/validation/schema" value="true"/> + <fileset dir="xml" includes="endpiece2.xml"/> + + <attribute name="http://xml.org/sax/features/validation" + value="true"/> + <attribute name="http://apache.org/xml/features/validation/schema" + value="true"/> </xmlvalidate> - </target> --> + </target> </project>
<<attachment: xmlvalidate.zip>>
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
