How to validate an XML file using Java with an XSD having an include?(如何使用具有包含 XSD 的 Java 验证 XML 文件?)
问题描述
我正在使用 Java 5 javax.xml.validation.Validator 来验证 XML 文件.我已经为一个只使用导入并且一切正常的模式完成了它.现在我正在尝试使用另一个使用导入和一个包含的模式进行验证.我遇到的问题是主模式中的元素被忽略,验证说它找不到他们的声明.
I'm using Java 5 javax.xml.validation.Validator to validate XML file. I've done it for one schema that uses only imports and everything works fine. Now I'm trying to validate with another schema that uses import and one include. The problem I have is that element in the main schema are ignored, the validation says it cannot find their declaration.
这是我构建架构的方式:
Here is how I build the Schema:
InputStream includeInputStream = getClass().getClassLoader().getResource("include.xsd").openStream();
InputStream importInputStream = getClass().getClassLoader().getResource("import.xsd").openStream();
InputStream mainInputStream = getClass().getClassLoader().getResource("main.xsd").openStream();
Source[] sourceSchema = new SAXSource[]{includeInputStream , importInputStream,
mainInputStream };
Schema schema = factory.newSchema(sourceSchema);
现在这里是 main.xsd 中声明的摘录
Now here is the extract of the declaration in main.xsd
<xsd:schema xmlns="http://schema.omg.org/spec/BPMN/2.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:import="http://www.foo.com/import" targetNamespace="http://main/namespace" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xsd:import namespace="http://www.foo.com/import" schemaLocation="import.xsd"/>
<xsd:include schemaLocation="include.xsd"/>
<xsd:element name="element" type="tElement"/>
<...>
</xsd:schema>
如果我将包含的 XSD 的代码复制到 main.xsd 中,它可以正常工作.如果我不这样做,验证不会找到元素"的声明.
If I copy the code of my included XSD in the main.xsd, it works fine. If I don't, validation doesn't find the declaration of "Element".
推荐答案
你需要使用一个 LSResourceResolver 使其工作.请看下面的示例代码.
you need to use an LSResourceResolver for this to work. please take a look at the sample code below.
验证方法:
// note that if your XML already declares the XSD to which it has to conform, then there's no need to declare the schemaName here
void validate(String xml, String schemaName) throws Exception {
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setNamespaceAware(true);
DocumentBuilder parser = builderFactory
.newDocumentBuilder();
// parse the XML into a document object
Document document = parser.parse(new StringInputStream(xml));
SchemaFactory factory = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
// associate the schema factory with the resource resolver, which is responsible for resolving the imported XSD's
factory.setResourceResolver(new ResourceResolver());
// note that if your XML already declares the XSD to which it has to conform, then there's no need to create a validator from a Schema object
Source schemaFile = new StreamSource(getClass().getClassLoader()
.getResourceAsStream(schemaName));
Schema schema = factory.newSchema(schemaFile);
Validator validator = schema.newValidator();
validator.validate(new DOMSource(document));
}
资源解析器实现:
public class ResourceResolver implements LSResourceResolver {
public LSInput resolveResource(String type, String namespaceURI,
String publicId, String systemId, String baseURI) {
// note: in this sample, the XSD's are expected to be in the root of the classpath
InputStream resourceAsStream = this.getClass().getClassLoader()
.getResourceAsStream(systemId);
return new Input(publicId, systemId, resourceAsStream);
}
}
资源解析器返回的输入实现:
The Input implemetation returned by the resource resolver:
public class Input implements LSInput {
private String publicId;
private String systemId;
public String getPublicId() {
return publicId;
}
public void setPublicId(String publicId) {
this.publicId = publicId;
}
public String getBaseURI() {
return null;
}
public InputStream getByteStream() {
return null;
}
public boolean getCertifiedText() {
return false;
}
public Reader getCharacterStream() {
return null;
}
public String getEncoding() {
return null;
}
public String getStringData() {
synchronized (inputStream) {
try {
byte[] input = new byte[inputStream.available()];
inputStream.read(input);
String contents = new String(input);
return contents;
} catch (IOException e) {
e.printStackTrace();
System.out.println("Exception " + e);
return null;
}
}
}
public void setBaseURI(String baseURI) {
}
public void setByteStream(InputStream byteStream) {
}
public void setCertifiedText(boolean certifiedText) {
}
public void setCharacterStream(Reader characterStream) {
}
public void setEncoding(String encoding) {
}
public void setStringData(String stringData) {
}
public String getSystemId() {
return systemId;
}
public void setSystemId(String systemId) {
this.systemId = systemId;
}
public BufferedInputStream getInputStream() {
return inputStream;
}
public void setInputStream(BufferedInputStream inputStream) {
this.inputStream = inputStream;
}
private BufferedInputStream inputStream;
public Input(String publicId, String sysId, InputStream input) {
this.publicId = publicId;
this.systemId = sysId;
this.inputStream = new BufferedInputStream(input);
}
}
这篇关于如何使用具有包含 XSD 的 Java 验证 XML 文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何使用具有包含 XSD 的 Java 验证 XML 文件?


- 如何使用WebFilter实现授权头检查 2022-01-01
- value & 是什么意思?0xff 在 Java 中做什么? 2022-01-01
- Java包名称中单词分隔符的约定是什么? 2022-01-01
- Spring Boot连接到使用仲裁器运行的MongoDB副本集 2022-01-01
- 从 finally 块返回时 Java 的奇怪行为 2022-01-01
- Eclipse 插件更新错误日志在哪里? 2022-01-01
- Jersey REST 客户端:发布多部分数据 2022-01-01
- C++ 和 Java 进程之间的共享内存 2022-01-01
- Safepoint+stats 日志,输出 JDK12 中没有 vmop 操作 2022-01-01
- 将log4j 1.2配置转换为log4j 2配置 2022-01-01