Browse Source

Add ability to set parser features in <xmlvalidate>.

Submitted by:	Nick Pellow <nick.pellow at mindmatics.de>


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@273345 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 22 years ago
parent
commit
9b7f00ab24
4 changed files with 171 additions and 43 deletions
  1. +39
    -4
      docs/manual/OptionalTasks/xmlvalidate.html
  2. +19
    -15
      src/etc/testcases/taskdefs/optional/xmlvalidate.xml
  3. +96
    -24
      src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java
  4. +17
    -0
      src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java

+ 39
- 4
docs/manual/OptionalTasks/xmlvalidate.html View File

@@ -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.</p>

<p>This task supports the use of nested <a
href="../CoreTypes/xmlcatalog.html">xmlcatalog</a> elements and/or nested
<tt>&lt;dtd&gt;</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>&lt;xmlcatalog&gt;</tt></a> elements
<li/><tt>&lt;dtd&gt;</tt> elements which are used to resolve DTDs and entities.
<li/><tt>&lt;attribute&gt;</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 @@ href="../CoreTypes/xmlcatalog.html">xmlcatalog</a> elements and/or nested
<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.
&lt;attribute&gt; 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 @@ Scan all XML files in the project, using a predefined catalog to map URIs to loc
&lt;/xmlvalidate&gt;
</pre>
Scan all XML files in the project, using the catalog defined inline.
<hr>

<pre>
&lt;xmlvalidate failonerror="yes" lenient="no" warn="yes"&gt;
&lt;fileset dir="xml" includes="**/*.xml"/&gt;
&lt;attribute name="http://xml.org/sax/features/validation" value="true"/&gt;
&lt;attribute name="http://apache.org/xml/features/validation/schema" value="true"/&gt;
&lt;/xmlvalidate&gt;
</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 &copy; 2001-2002 Apache Software Foundation. All rights
Reserved.</p>



+ 19
- 15
src/etc/testcases/taskdefs/optional/xmlvalidate.xml View File

@@ -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>

+ 96
- 24
src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java View File

@@ -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 <a href="mailto:raphael.pierquin@agisphere.com">raphael.pierquin@agisphere.com</a>
* @author Nick Pellow <a href="mailto:nick@svana.org">nick@svana.org</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 @@ 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 <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 @@ 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
* <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.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 <a href="mailto:nick@svana.org">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;
}
}
}

+ 17
- 0
src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java View File

@@ -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");

}
}

Loading…
Cancel
Save