我试图验证对许多不同的模式(道歉了人为的例子)的XML文件:
c.xsd特别是进口b.xsd和b.xsd进口a.xsd,使用:
<xs:include schemaLocation="b.xsd"/>
我试图通过的Xerces以下方式来做到这一点:
XMLSchemaFactory xmlSchemaFactory = new XMLSchemaFactory();
Schema schema = xmlSchemaFactory.newSchema(new StreamSource[] { new StreamSource(this.getClass().getResourceAsStream("a.xsd"), "a.xsd"),
new StreamSource(this.getClass().getResourceAsStream("b.xsd"), "b.xsd"),
new StreamSource(this.getClass().getResourceAsStream("c.xsd"), "c.xsd")});
Validator validator = schema.newValidator();
validator.validate(new StreamSource(new StringReader(xmlContent)));
但这未能导入所有三个正确导致的模式无法解析名称“嗒嗒”来一个(N)“组”的组成部分。
我已经验证了这种成功使用Python,但其与Java 6.0和Xerces 2.8.1实际问题。 任何人都可以提出什么错在这里,或更简单的方法来验证我的XML文档?
Answer 1:
所以以防万一别人运行到同样的问题在这里,我需要加载从单元测试父模式(和隐含的子模式) - 作为一种资源 - 验证XML字符串。 我使用了Xerces XMLSchemFactory与Java 6的验证器一起做到这一点。
为了通过包括正确加载子模式的,我不得不写一个自定义资源解析器。 代码可以在这里找到:
https://code.google.com/p/xmlsanity/source/browse/src/com/arc90/xmlsanity/validation/ResourceResolver.java
要使用解析器指定它在架构工厂:
xmlSchemaFactory.setResourceResolver(new ResourceResolver());
它会用它通过类路径来解决你的资源(在我的情况下,来自的src / main /资源)。 任何意见都在此欢迎...
Answer 2:
http://www.kdgregory.com/index.php?page=xml.parsing节“ 为一个单一的文件多模式 ”
我的解决方案基于这样的文件:
URL xsdUrlA = this.getClass().getResource("a.xsd");
URL xsdUrlB = this.getClass().getResource("b.xsd");
URL xsdUrlC = this.getClass().getResource("c.xsd");
SchemaFactory schemaFactory = schemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
//---
String W3C_XSD_TOP_ELEMENT =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
+ "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\">\n"
+ "<xs:include schemaLocation=\"" +xsdUrlA.getPath() +"\"/>\n"
+ "<xs:include schemaLocation=\"" +xsdUrlB.getPath() +"\"/>\n"
+ "<xs:include schemaLocation=\"" +xsdUrlC.getPath() +"\"/>\n"
+"</xs:schema>";
Schema schema = schemaFactory.newSchema(new StreamSource(new StringReader(W3C_XSD_TOP_ELEMENT), "xsdTop"));
Answer 3:
中的Xerces架构的东西(一)非常,非常迂腐,和(b)给出了完全无用的错误消息,当它不喜欢它发现。 这是一个令人沮丧的组合。
在Python架构的东西可能有很多更宽容,并让架构中的小错误,走过去的报道。
现在,如果如你所说,c.xsd包括b.xsd和b.xsd包括a.xsd,那么就没有必要所有三个加载到架构工厂。 它不仅是不必要的,它可能会混淆Xerces和导致错误,所以这可能是你的问题。 只是通过c.xsd工厂,并让它解决b.xsd和a.xsd本身,它应该做的相对c.xsd。
Answer 4:
从Xerces的文档: http://xerces.apache.org/xerces2-j/faq-xs.html
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
...
StreamSource[] schemaDocuments = /* created by your application */;
Source instanceDocument = /* created by your application */;
SchemaFactory sf = SchemaFactory.newInstance(
"http://www.w3.org/XML/XMLSchema/v1.1");
Schema s = sf.newSchema(schemaDocuments);
Validator v = s.newValidator();
v.validate(instanceDocument);
Answer 5:
最后我用这个:
import org.apache.xerces.parsers.SAXParser;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
import java.io.IOException;
.
.
.
try {
SAXParser parser = new SAXParser();
parser.setFeature("http://xml.org/sax/features/validation", true);
parser.setFeature("http://apache.org/xml/features/validation/schema", true);
parser.setFeature("http://apache.org/xml/features/validation/schema-full-checking", true);
parser.setProperty("http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation", "http://your_url_schema_location");
Validator handler = new Validator();
parser.setErrorHandler(handler);
parser.parse("file:///" + "/home/user/myfile.xml");
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException ex) {
e.printStackTrace();
}
class Validator extends DefaultHandler {
public boolean validationError = false;
public SAXParseException saxParseException = null;
public void error(SAXParseException exception)
throws SAXException {
validationError = true;
saxParseException = exception;
}
public void fatalError(SAXParseException exception)
throws SAXException {
validationError = true;
saxParseException = exception;
}
public void warning(SAXParseException exception)
throws SAXException {
}
}
记住更改:
1)参数的“http:// your_url_schema_location”为您XSD文件的位置。
2)字符串“/home/user/myfile.xml”为一个指向您的XML文件。
我没有设置变量: -Djavax.xml.validation.SchemaFactory:http://www.w3.org/2001/XMLSchema=org.apache.xerces.jaxp.validation.XMLSchemaFactory
Answer 6:
我面临着同样的问题,调查后发现,这个解决方案。 这个对我有用。
Enum
来设置不同XSDs
:
public enum XsdFile {
// @formatter:off
A("a.xsd"),
B("b.xsd"),
C("c.xsd");
// @formatter:on
private final String value;
private XsdFile(String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
}
方法来验证:
public static void validateXmlAgainstManyXsds() {
final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
String xmlFile;
xmlFile = "example.xml";
// Use of Enum class in order to get the different XSDs
Source[] sources = new Source[XsdFile.class.getEnumConstants().length];
for (XsdFile xsdFile : XsdFile.class.getEnumConstants()) {
sources[xsdFile.ordinal()] = new StreamSource(xsdFile.getValue());
}
try {
final Schema schema = schemaFactory.newSchema(sources);
final Validator validator = schema.newValidator();
System.out.println("Validating " + xmlFile + " against XSDs " + Arrays.toString(sources));
validator.validate(new StreamSource(new File(xmlFile)));
} catch (Exception exception) {
System.out.println("ERROR: Unable to validate " + xmlFile + " against XSDs " + Arrays.toString(sources)
+ " - " + exception);
}
System.out.println("Validation process completed.");
}
文章来源: Validate an XML File Against Multiple Schema Definitions