Nous avons récemment passé nos projets à Java 1.6. Lors de l'exécution des tests, j'ai découvert qu'en utilisant 1.6 une exception SAXParseException n'a pas été levée en utilisant 1.5.Différence dans DocumentBuilder.parse lors de l'utilisation de JRE 1.5 et JDK 1.6
Ci-dessous est mon code de test pour démontrer le problème.
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.SchemaFactory;
import org.junit.Test;
import org.xml.sax.InputSource;
import org.xml.sax.SAXParseException;
/**
* Test class to demonstrate the difference between JDK 1.5 to JDK 1.6.
*
* Seen on Linux:
*
* <pre>
* #java version "1.6.0_18"
* Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
* Java HotSpot(TM) Server VM (build 16.0-b13, mixed mode)
* </pre>
*
* Seen on OSX:
*
* <pre>
* java version "1.6.0_17"
* Java(TM) SE Runtime Environment (build 1.6.0_17-b04-248-10M3025)
* Java HotSpot(TM) 64-Bit Server VM (build 14.3-b01-101, mixed mode)
* </pre>
*
* @author dhiller (creator)
* @author $Author$ (last editor)
* @version $Revision$
* @since 12.03.2010 11:32:31
*/
public class TestXMLValidation {
/**
* Tests the schema validation of an XML against a simple schema.
*
* @throws Exception
* Falls ein Fehler auftritt
* @throws junit.framework.AssertionFailedError
* Falls eine Unit-Test-Pruefung fehlschlaegt
*/
@Test(expected = SAXParseException.class)
public void testValidate() throws Exception {
final StreamSource schema = new StreamSource(new StringReader("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" "
+ "elementFormDefault=\"qualified\" xmlns:xsd=\"undefined\">" + "<xs:element name=\"Test\"/>" + "</xs:schema>"));
final String xml = "<Test42/>";
final DocumentBuilderFactory newFactory = DocumentBuilderFactory.newInstance();
newFactory.setSchema(SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema").newSchema(schema));
final DocumentBuilder documentBuilder = newFactory.newDocumentBuilder();
documentBuilder.parse(new InputSource(new StringReader(xml)));
}
}
Lorsque vous utilisez une machine virtuelle Java 1.5 passe le test, le 1.6, il échoue avec "exception attendue SAXParseException".
Le Javadoc de la DocumentBuilderFactory.setSchema(Schema) Méthode dit:
Lorsque des erreurs sont détectées par le validateur, l'analyseur est responsable de les signaler à l' spécifié par l'utilisateur ErrorHandler (ou si le gestionnaire d'erreurs est pas défini, ignorez-les ou lancez-les eux), comme toutes les autres erreurs trouvées par l'analyseur lui-même. En d'autres mots , si le ErrorHandler spécifié par l'utilisateur est défini, il doit recevoir ces erreurs, et sinon, ils doivent être traités selon l'erreur par défaut spécifique mise en œuvre règles de gestion.
Le Javadoc de la méthode DocumentBuilder.parse(InputSource) dit:
BTW: J'essayé d'installer un gestionnaire d'erreur via setErrorHandler, mais il n'y a toujours pas d'exception.
Ma question:
Ce qui a changé à 1,6 qui empêche la validation de schéma pour lancer une SAXParseException? Est-ce lié au schéma ou au xml que j'ai essayé d'analyser?
Mise à jour:
Le code suivant fonctionne sur 1,5 et 1,6 comme je l'ai été désirais:
@Test(expected = SAXParseException.class)
public void testValidate() throws Exception {
final StreamSource schema = new StreamSource(new StringReader("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" "
+ "elementFormDefault=\"qualified\" xmlns:xsd=\"undefined\">" + "<xs:element name=\"Test\"/>" + "</xs:schema>"));
final String xml = "<Test42/>";
final DocumentBuilderFactory newFactory = DocumentBuilderFactory.newInstance();
final Schema newSchema = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema").newSchema(schema);
newFactory.setSchema(newSchema);
final Validator newValidator = newSchema.newValidator();
final Source is = new StreamSource(new StringReader(xml));
try {
newValidator.validate((Source) is);
}
catch (Exception e) {
e.printStackTrace();
throw e;
}
final DocumentBuilder documentBuilder = newFactory.newDocumentBuilder();
documentBuilder.parse(new InputSource(new StringReader(xml)));
}
La solution semble être d'utiliser explicitement une instance de validateur créée à partir de l'instance de schéma . J'ai trouvé la solution here
Cependant, je ne sais pas pourquoi c'est ...