From 9b7f00ab245e2c75e3e57d0de1782c4a8b3d50eb Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Mon, 23 Sep 2002 14:59:42 +0000 Subject: [PATCH] Add ability to set parser features in . Submitted by: Nick Pellow git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@273345 13f79535-47bb-0310-9956-ffa450edef68 --- docs/manual/OptionalTasks/xmlvalidate.html | 43 ++++++- .../taskdefs/optional/xmlvalidate.xml | 34 ++--- .../taskdefs/optional/XMLValidateTask.java | 120 ++++++++++++++---- .../taskdefs/optional/XmlValidateTest.java | 17 +++ 4 files changed, 171 insertions(+), 43 deletions(-) diff --git a/docs/manual/OptionalTasks/xmlvalidate.html b/docs/manual/OptionalTasks/xmlvalidate.html index 71ead0e57..aea5f3864 100644 --- a/docs/manual/OptionalTasks/xmlvalidate.html +++ b/docs/manual/OptionalTasks/xmlvalidate.html @@ -14,9 +14,11 @@ task uses the SAX2 parser implementation provided by JAXP by default (probably the one that is used by Ant itself), but one can specify any SAX1/2 parser if needed.

-

This task supports the use of nested xmlcatalog elements and/or nested -<dtd> elements which are used to resolve DTDs and entities.

+

This task supports the use of nested +

  • <xmlcatalog> elements +
  • <dtd> elements which are used to resolve DTDs and entities. +
  • <attribute> elements which are used to set features on the parser. These can be any number of http://xml.org/sax/features/ or other features that your parser may support. +

    Parameters

    @@ -84,6 +86,30 @@ href="../CoreTypes/xmlcatalog.html">xmlcatalog elements and/or nested

    xmlcatalog

    The xmlcatalog element is used to perform Entity resolution.

    +

    attribute

    +

    The attribute element is used to set SAX Parser features. +There can an arbitrary amount of attribute set as defined here: + http://xml.org/sax/features/ +A feature essentialy changes the mode of the parser. +<attribute> an attribute is used to set specific features on the parser. +

    + + + + + + + + + + + + + + + +
    AttributeDescriptionRequired
    nameThe name of the featureYes
    valueThe boolean value of the featureYes
    +

    Examples

    @@ -128,8 +154,17 @@ Scan all XML files in the project, using a predefined catalog to map URIs to loc </xmlvalidate> Scan all XML files in the project, using the catalog defined inline. -
    +
    +<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>
    +
    +Validate all .xml files in xml directory with the parser configured to perform schema validation. Note: The parser must support the
    http://apache.org/xml/features/validation/schema
    feature. +
    +

    Copyright © 2001-2002 Apache Software Foundation. All rights Reserved.

    diff --git a/src/etc/testcases/taskdefs/optional/xmlvalidate.xml b/src/etc/testcases/taskdefs/optional/xmlvalidate.xml index 74546259f..35bc9ce9e 100644 --- a/src/etc/testcases/taskdefs/optional/xmlvalidate.xml +++ b/src/etc/testcases/taskdefs/optional/xmlvalidate.xml @@ -38,25 +38,29 @@ + - - + diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java index 8aa3039bb..0f78f3e81 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java @@ -58,9 +58,8 @@ import java.io.FileReader; 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 @@ import org.xml.sax.helpers.ParserAdapter; * (probably the one that is used by Ant itself), but one can specify any * SAX1/2 parser if needed * @author Raphael Pierquin raphael.pierquin@agisphere.com + * @author Nick Pellow nick@svana.org */ 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 @@ public class XMLValidateTask extends Task { 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 true. *

    - * If set to true (default), throw a buildException if the + * If set to true (default), throw a buildException if the * parser yields an error. */ public void setFailOnError(boolean fail) { @@ -194,7 +197,7 @@ public class XMLValidateTask extends Task { } /** - * 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 @@ public class XMLValidateTask extends Task { filesets.addElement(set); } + /** + * Add an attribute nested element. This is used for setting arbitrary + * features of the SAX parser. + * Valid attributes + * include + * @since ant1.6 + */ + public Attribute createAttribute() { + final Attribute feature = new Attribute(); + attributeList.addElement(feature); + return feature; + } + public void init() throws BuildException { super.init(); xmlCatalog.setProject(getProject()); @@ -294,7 +310,7 @@ public class XMLValidateTask extends Task { reader = JAXPUtils.getParser(); } } else { - + Class readerClass = null; try { // load the parser class @@ -318,15 +334,15 @@ public class XMLValidateTask extends Task { // 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 @@ public class XMLValidateTask extends Task { + " 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.elementAt(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 @@ public class XMLValidateTask extends Task { 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 @@ public class XMLValidateTask extends Task { 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); } @@ -482,4 +505,53 @@ public class XMLValidateTask extends Task { return e.getMessage(); } } + + /** + * The class to create to set a feature of the parser. + * @since ant1.6 + * @author Nick Pellow + */ + public class Attribute { + /** The name of the attribute to set. + * + * Valid attributes include. + */ + 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; + } + } } diff --git a/src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java b/src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java index c532227e7..4e761d8fb 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java @@ -94,6 +94,7 @@ public class XmlValidateTest extends BuildFileTest { * The teardown method for JUnit */ public void tearDown() { + } @@ -125,4 +126,20 @@ public class XmlValidateTest extends BuildFileTest { 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"); + + } }