我使用Xerces2 Java Parser来验证基于XML Schema 1.1的XML文件。 我已经在maven存储库中导入了Apache Xerces2 Java 2.11.0(XML Schema 1.1)(Beta)的二进制包附带的所有jar。经过一些配置,它工作正常。
我的目标是验证不包含针对XML Schema 1.1的命名空间的XML文件。
架构:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xerces="http://xerces.apache.org">
<xs:element name="root" type="CT_ROOT" />
<xs:complexType name="CT_ROOT">
<xs:sequence>
<xs:element name="myid" type="xs:string" minOccurs="1" />
<xs:element name="mytest" type="ST_Integer" minOccurs="1" />
</xs:sequence>
<xs:assert test="myid gt 100" xerces:message="myid has to be greater than 100" />
</xs:complexType>
<xs:simpleType name="ST_Integer">
<xs:restriction base="xs:integer" xmlns:xerces="http://xerces.apache.org">
<xs:minInclusive value="10" />
<xs:assertion test="$value mod 2 eq 0" xerces:message="Value of element 'test' must be divisible by 2"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<myid>123</myid>
<mytest>60</mytest>
</root>
Java代码:
@Test
public void validateWithXerces() {
System.setProperty("jaxp.debug", "true");
StreamSource schemaDocument = new StreamSource(schemaDocumentString);
Source instanceDocument = new StreamSource(new File(instanceDocumentString));
SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/XML/XMLSchema/v1.1");
Schema schema;
try {
schema = schemaFactory.newSchema(schemaDocument);
Validator validator = schema.newValidator();
validator.validate(instanceDocument);
} catch (Exception e) {
e.printStackTrace();
}
}
问题是当JUnit测试运行时,QName类会断言命名空间并且失败。特定测试的目标不是命名空间的有效性,因为它有意识地缺席,而是XML验证。因此,我们可以忽略命名空间断言。
引发的异常是(某些行已被省略):
java.lang.AssertionError
at org.eclipse.wst.xml.xpath2.processor.internal.types.QName.namespace(QName.java:235)
at org.eclipse.wst.xml.xpath2.processor.DefaultEvaluator.evaluate(DefaultEvaluator.java:239)
at org.apache.xerces.impl.xs.AbstractPsychoPathImpl.evaluatePsychoPathExpr(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.jaxp.validation.ValidatorImpl.validate(Unknown Source)
at javax.xml.validation.Validator.validate(Validator.java:124)
答案 0 :(得分:0)
解决方案就是禁用断言。您可以禁用某个类或每个类的断言。
第一种解决方案似乎更合适。在这种情况下,请在测试类中添加以下代码。只需确保,这段代码是在验证器调用之前。
ClassLoader loader = this.getClass().getClassLoader();
loader.setClassAssertionStatus("org.eclipse.wst.xml.xpath2.processor.internal.types.QName", false);
如果要禁用每个类的断言,可以使用Maven:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<enableAssertions>false</enableAssertions>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>