java.lang.AssertionError使用没有命名空间的XML Schema 1.1的xercesImpl

时间:2015-03-26 17:53:37

标签: java xml validation xsd xerces2-j

我使用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)

1 个答案:

答案 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>