[英]Difference in DocumentBuilder.parse when using JRE 1.5 and JDK 1.6
最近我們最終將項目轉換為Java 1.6。 在執行測試時,我發現使用1.6時,不會拋出使用1.5拋出的SAXParseException。
下面是我的測試代碼來演示這個問題。
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 ) ) );
}
}
當使用JVM 1.5時,測試通過,在1.6上它失敗並出現“Expected exception SAXParseException”。
DocumentBuilderFactory.setSchema(Schema)方法的Javadoc說:
當驗證程序發現錯誤時,解析器負責將它們報告給用戶指定的ErrorHandler(或者如果未設置錯誤處理程序,則忽略它們或拋出它們),就像解析器本身找到的任何其他錯誤一樣。 換句話說,如果設置了用戶指定的ErrorHandler,它必須接收這些錯誤,如果沒有,則必須根據特定於實現的默認錯誤處理規則來處理它們。
DocumentBuilder.parse(InputSource)方法的Javadoc說:
BTW:我嘗試通過setErrorHandler設置錯誤處理程序,但仍然沒有異常。
現在我的問題:
什么已更改為1.6,阻止架構驗證拋出SAXParseException? 它與我試圖解析的模式或xml有關嗎?
更新:
以下代碼適用於1.5和1.6,因為我一直希望:
@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 ) ) );
}
解決方案似乎是顯式使用從Schema實例創建的Validator實例。 我在這里找到了解決方案
我還不確定那是為什么......
顯然,不符合模式的文檔只能對默認錯誤處理程序中的stderr進行溫和的譴責。 我的解決方案是用更嚴格的錯誤處理程序替換默認錯誤處理程序:
// builder is my DocumentBuilder
builder.setErrorHandler(new ErrorHandler() {
@Override
public void error(SAXParseException arg0) throws SAXException {
throw arg0;
}
@Override
public void fatalError(SAXParseException arg0) throws SAXException {
throw arg0;
}
@Override
public void warning(SAXParseException arg0) throws SAXException {
throw arg0;
}
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.