英文:
Validating xml through xsd files inside a JAR
问题
我尝试使用XSD验证XML。到目前为止,一切都正常:
File xsdFile = null;
Source source = new StreamSource(new StringReader(xmlString));
try {
xsdFile = new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD).getFile();
} catch (IOException e) {
throw new FacturxException(e.getMessage());
}
try {
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(xsdFile);
Validator validator = schema.newValidator();
validator.validate(source);
return true;
} catch (SAXException | IOException e) {
throw a FacturxException(e.getLocalizedMessage());
}
我的问题是:
如果将其编译为JAR文件并使用验证器调用该方法,会出现错误。事实上,似乎无法获取相关的XSD文件。
我尝试以以下方式解决此问题:
Source[] sources = new Source[] {
new StreamSource(
new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD_QUALIFIED_DATA)
.getInputStream()),
new StreamSource(
new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD_REUSABLE)
.getInputStream()),
new StreamSource(
new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD_UNQUALIFIED_DATA)
.getInputStream()),
new StreamSource(
new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD).getInputStream())
}
显然,我可以访问这些XSD文件,但它返回src-resolve: Cannot resolve the name 'udt:IDType' to a(n) 'type definition' component
。如果更改XSD文件的顺序,错误也会不同。
我在整天内陷入困境。
英文:
I try to validate an xml using xsd. So far, everything works fine:
File xsdFile = null;
Source source = new StreamSource(new StringReader(xmlString));
try {
xsdFile = new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD).getFile();
} catch (IOException e) {
throw new FacturxException(e.getMessage());
}
try {
SchemaFactory schemaFactory = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(xsdFile);
Validator validator = schema.newValidator();
validator.validate(source);
return true;
} catch (SAXException | IOException e) {
throw new FacturxException(e.getLocalizedMessage());
}
My issue is the following:
If i compile it in a jar and call the method using the validator, i have errors. As a matter of fact it seems that i can't get the related xsd files.
I tried to solve this issue this way:
Source[] sources = sources = new Source[] {
new StreamSource(
new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD_QUALIFIED_DATA)
.getInputStream()),
new StreamSource(
new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD_REUSABLE)
.getInputStream()),
new StreamSource(
new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD_UNQUALIFIED_DATA)
.getInputStream()),
new StreamSource(
new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD).getInputStream())
Apparently I do have access to those xsd files but it returns src-resolve: Cannot resolve the name 'udt:IDType' to a(n) 'type definition' component
. If i change xsd files order, errors differs...
I'm stuck for the whole day on this.
答案1
得分: 1
如果您以没有systemId属性的StreamSource
提供输入,那么系统不知道输入流的来源,这意味着它无法解析输入流中包含的任何相对URI。您需要提供一个基本URI。
您还没有说明您使用的模式处理器和细节可能有所不同。我认为最近在Saxon中有一个情况,我们发现classpath:
URI方案被正确解析,以查找同一JAR文件中的其他资源,但这不一定适用于您的情况;您可能需要提供一个URIResolver或SchemaResolver。但第一步是确保基本URI是已知的。
英文:
If you supply the input as a StreamSource
with no systemId property, then the system doesn't know where the input stream came from, which means it can't resolve any relative URIs contained in that input stream. You need to supply a base URI.
You haven't said which schema processor you are using and the details may vary. I think we had a case recently in Saxon where we found that the classpath:
URI scheme was being correctly resolved to find other resources in the same JAR file, but this will not necessarily be the case for your situation; you may need to provide a URIResolver or SchemaResolver. But the first step is to make sure the base URI is known.
答案2
得分: 1
根据Michael Kay的观察,我实现了一个设置SystemId的方法:
private static Source[] buildSources(String pattern) throws SAXException, IOException {
List<Source> sources = new ArrayList<>();
PathMatchingResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
Resource[] resources = patternResolver.getResources(pattern);
for (Resource resource : resources) {
StreamSource dtd = new StreamSource(resource.getInputStream());
dtd.setSystemId(resource.getURI().toString());
sources.add(dtd);
}
return sources.toArray(new Source[sources.size()]);
}
模式看起来像这样:
"classpath:xsd/BASIC-WL_XSD/**/*.xsd"
xsd文件存储在资源文件夹中...
英文:
Based on Michael Kay observation, I implpemented a method to set the SystemId:
private static Source[] buildSources(String pattern) throws SAXException, IOException {
List<Source> sources = new ArrayList<>();
PathMatchingResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
Resource[] resources = patternResolver.getResources(pattern);
for (Resource resource : resources) {
StreamSource dtd = new StreamSource(resource.getInputStream());
dtd.setSystemId(resource.getURI().toString());
sources.add(dtd);
}
return sources.toArray(new Source[sources.size()]);
}
Pattern looks like this:
"classpath:xsd/BASIC-WL_XSD/**/*.xsd"
xsd files are stored in resources folder ...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论