我必须根据 xsd 语法验证 xml 文件。以下是对我的原始需求的简单模拟。
有一个名为
<foo>
的根元素
它有四个子元素,为了简单起见,我们将它们表示为 child1、child2、child3 和 child4。
<foo />
成为一个有效的xml。在浏览了一些现有的答案后,我发现 [1] 中给出的更详细的答案 不是我的问题的实际解决方案,因为有超过 10 个子元素 会产生组合爆炸。然后,在答案的后半部分指出 xsd 1.1 放宽了一些限制,因此允许使用
<xs:all>
和maxOccurs="unbounded"
。
然后我使用 xerces 库,并尝试将 xsd 1.1 功能与 java 一起使用。以下是我的示例代码。然而, 当 xml 中存在多个元素时,出现以下错误。 cvc-complex-type.2.4.a:发现以元素“child1”开头的无效内容。需要“{child2, child3, child4}”之一。
带有 xsd 1.1 扩展的 xsd 模式。
<?xml version="1.1" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
elementFormDefault="qualified" vc:minVersion="1.1">
<xs:element name="foo">
<xs:complexType>
<xs:all>
<xs:element name="child1" vc:minOccurs="0"
vc:maxOccurs="unbounded" />
<xs:element name="child2" vc:minOccurs="0"
vc:maxOccurs="unbounded" />
<xs:element name="child3" type="xs:string" />
<xs:element name="child4" type="xs:string" />
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
xml有效负载
<foo>
<child1> a </child1>
<child1> b </child1>
<child3> c </child3>
<child2> d </child2>
<child4> e </child4>
<child2> g </child2>
<child1> f </child1>
</foo>
maven 依赖
<dependency>
<groupId>org.opengis.cite.xerces</groupId>
<artifactId>xercesImpl-xsd11</artifactId>
<version>2.12-beta-r1667115</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.exist-db.thirdparty.org.eclipse.wst.xml</groupId>
<artifactId>xpath2</artifactId>
<version>1.2.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>edu.princeton.cup</groupId>
<artifactId>java-cup</artifactId>
<version>10k</version>
<scope>runtime</scope>
</dependency>
或
<dependency>
<groupId>org.ibissource</groupId>
<artifactId>ibis-xerces</artifactId>
<version>2.12.2-xml-schema-1.1</version>
</dependency>
示例 java 代码:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.StringJoiner;
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;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public class CrtDataValidatorImpl {
public void validate(String xsdFilePath, String data) {
final XmlErrorHandler errorHandler = new XmlErrorHandler();
try {
final File schemaFile = new File(xsdFilePath);
final SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/XML/XMLSchema/v1.1");
final Schema schema = schemaFactory.newSchema(schemaFile);
final Validator validator = schema.newValidator();
validator.setErrorHandler(errorHandler);
final Source xmlSource = new StreamSource(new StringReader(data));
validator.validate(xmlSource);
} catch (SAXException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
}
System.out.println(String.format("Number of errors: %s", errorHandler.getExceptions().size()));
for (Exception ex : errorHandler.getExceptions())
System.out.println(ex.getMessage());
}
public static void main(String[] args) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader("./src/main/resources/simple-payload.xml"))) {
final StringJoiner sj = new StringJoiner("\n");
String line = br.readLine();
while (line != null) {
sj.add(line);
line = br.readLine();
}
System.out.println(sj.toString());
new CrtDataValidatorImpl().validate("./src/main/resources/sample.xsd", sj.toString());
}
}
static class XmlErrorHandler implements ErrorHandler {
private Collection<SAXParseException> exceptions;
public XmlErrorHandler() {
this.exceptions = new ArrayList<>();
}
public Collection<SAXParseException> getExceptions() {
return exceptions;
}
@Override
public void warning(SAXParseException exception) {
exceptions.add(exception);
}
@Override
public void error(SAXParseException exception) {
exceptions.add(exception);
}
@Override
public void fatalError(SAXParseException exception) {
exceptions.add(exception);
}
}
}
我尝试调试这个问题,不幸的是,它并没有为找出原因提供任何帮助。这里缺少什么?任何帮助,将不胜感激。谢谢。