如何确定坏模式?
How to determine the bad schema?
我正在编写一个小应用程序来验证“候选”xml 文件是否与存储在文件夹中的已知良好模式文件的“银行”...
事实证明,已知的良好模式文件本身会引发问题!
我将模式文件(21 个文件,我很确定这些模式中的大多数不仅引用它们自己,而且其中一些使用文件夹中的其他模式)加载到我的“模式”中的方式 space":
// Load schemas into schema space:
Schema mySchema;
try {
SchemaFactory mySchemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
mySchemaFactory.setResourceResolver(new ResourceResolver(pathToSchemasFolder));
mySchema = mySchemaFactory.newSchema(primeAllSchemaDocsFromFolder(pathToSchemasFolder));
System.out.println("Schemas loaded");
} catch (SAXException e) {
throw new RuntimeException("Schema loading failed: " + e);
}
我得到:
Exception in thread "main" java.lang.RuntimeException: Schema loading failed: org.xml.sax.SAXParseException; lineNumber: 232; columnNumber: 5; s4s-elt-chara...
- 注意它给了我行号和列号但没有文件名...
我在验证时已经在使用自定义 XsdErrorHandler()
:
// Validate xml file within schema space:
try {
Validator validator = mySchema.newValidator();
validator.setErrorHandler(new XsdErrorHandler());
validator.validate(getSingleXmlFileStreamSource(pathToXmlCandidateFile));
System.out.println("Validation is successful");
但是,在调试时,我发现它没有被调用...这是有道理的,因为失败的部分是加载模式,在我将 ErrorHandler 设置为 Validator 之前完成的一些事情...
我想知道是否有办法为架构加载过程设置错误处理程序?
或者您可以与我分享任何其他技术来查找有问题的架构名称?
(例如:将模式文件逐步添加到模式 space 中,每次测试模式 space 是否有效 - 没有任何无效的模式定义)
有一种方法 SchemaFactory.setErrorHandler() 可以让您在架构编译期间拦截错误。
当您生成 StreamSource
时,您应该提供 publicId
属性。这个属性不影响解析,但在异常中提供了有用的信息:
* <p>The public identifier is always optional: if the application
* writer includes one, it will be provided as part of the
* location information.</p>
如果您将模式文件名用作 publicId
,您将能够从 SAXParseException.
中检索它
从原始提问者编辑:
由于我在 newSchema() 中使用 Source[],我可以为每个 Source 准备输入以包括提到的方法,如下所示:
Source[] sourceArray = new Source[numberOfSchemaFiles];
for (int i=0; i<numberOfSchemaFiles ; i++) {
String currentFileName = schemaFiles[i].getName();
try {
StreamSource currentStreamSource = new StreamSource(
new FileInputStream(directoryPath + currentFileName)
);
currentStreamSource.setPublicId(currentFileName);
sourceArray[i] = currentStreamSource;
} catch (FileNotFoundException e) {
throw new RuntimeException("Cannot find file: " + directoryPath + currentFileName);
}
我正在编写一个小应用程序来验证“候选”xml 文件是否与存储在文件夹中的已知良好模式文件的“银行”...
事实证明,已知的良好模式文件本身会引发问题!
我将模式文件(21 个文件,我很确定这些模式中的大多数不仅引用它们自己,而且其中一些使用文件夹中的其他模式)加载到我的“模式”中的方式 space":
// Load schemas into schema space:
Schema mySchema;
try {
SchemaFactory mySchemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
mySchemaFactory.setResourceResolver(new ResourceResolver(pathToSchemasFolder));
mySchema = mySchemaFactory.newSchema(primeAllSchemaDocsFromFolder(pathToSchemasFolder));
System.out.println("Schemas loaded");
} catch (SAXException e) {
throw new RuntimeException("Schema loading failed: " + e);
}
我得到:
Exception in thread "main" java.lang.RuntimeException: Schema loading failed: org.xml.sax.SAXParseException; lineNumber: 232; columnNumber: 5; s4s-elt-chara...
- 注意它给了我行号和列号但没有文件名...
我在验证时已经在使用自定义 XsdErrorHandler()
:
// Validate xml file within schema space:
try {
Validator validator = mySchema.newValidator();
validator.setErrorHandler(new XsdErrorHandler());
validator.validate(getSingleXmlFileStreamSource(pathToXmlCandidateFile));
System.out.println("Validation is successful");
但是,在调试时,我发现它没有被调用...这是有道理的,因为失败的部分是加载模式,在我将 ErrorHandler 设置为 Validator 之前完成的一些事情...
我想知道是否有办法为架构加载过程设置错误处理程序?
或者您可以与我分享任何其他技术来查找有问题的架构名称? (例如:将模式文件逐步添加到模式 space 中,每次测试模式 space 是否有效 - 没有任何无效的模式定义)
有一种方法 SchemaFactory.setErrorHandler() 可以让您在架构编译期间拦截错误。
当您生成 StreamSource
时,您应该提供 publicId
属性。这个属性不影响解析,但在异常中提供了有用的信息:
* <p>The public identifier is always optional: if the application
* writer includes one, it will be provided as part of the
* location information.</p>
如果您将模式文件名用作 publicId
,您将能够从 SAXParseException.
从原始提问者编辑: 由于我在 newSchema() 中使用 Source[],我可以为每个 Source 准备输入以包括提到的方法,如下所示:
Source[] sourceArray = new Source[numberOfSchemaFiles];
for (int i=0; i<numberOfSchemaFiles ; i++) {
String currentFileName = schemaFiles[i].getName();
try {
StreamSource currentStreamSource = new StreamSource(
new FileInputStream(directoryPath + currentFileName)
);
currentStreamSource.setPublicId(currentFileName);
sourceArray[i] = currentStreamSource;
} catch (FileNotFoundException e) {
throw new RuntimeException("Cannot find file: " + directoryPath + currentFileName);
}