将assert与导入的带有枚举的simpleType结合使用

时间:2018-01-22 20:24:05

标签: java xml xsd

我正在使用xsd构建服务以验证申请表,这些申请表将使用常见类型,因此我希望能够重复使用它们。

但我也想使用xsd 1.1断言来验证字段的组合。

我无法将我的常用类型移动到单独的xsd并且还使用断言,断言仅适用于同一xsd中的类型。

这些是我创建的初始xsd,xml和代码,常见类型“CoverType”仍在ApplicationForm模式中,xsd作为本地文件:

Applicationform.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:xerces="http://xerces.apache.org"
           xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning">
    <xs:element name="policy" vc:minVersion="1.1">
        <xs:complexType>
            <xs:sequence>
                <xs:element type="xs:string" name="surname" minOccurs="1" />
                <xs:element name="coverType" type="CoverType" minOccurs="1" />
                <xs:element name="annuityPercentage" type="xs:decimal" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
            <xs:assert test="(coverType = 'LEVEL' or coverType = 'LINEAIR') or (annuityPercentage > 0) "/>
        </xs:complexType>
    </xs:element>
    <xs:simpleType name="CoverType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="LEVEL"/>
            <xs:enumeration value="ANNUITY"/>
            <xs:enumeration value="LINEAIR"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

这是相应的test.xml:

<?xml version="1.0" encoding="UTF-8"?>
<policy>
    <surname>test</surname>
    <coverType>ANNUITY</coverType>
    <annuityPercentage>0</annuityPercentage>
</policy>

我正在使用Java和Xerces J 2.11来加载ApplicationForm.xsd,这是一段代码片段:

public class ValidationHandler {
    static final String xsdLocationtest = "C:/dev/workspace/xsd/ApplicationForm.xsd";
    static final String language = "http://www.w3.org/XML/XMLSchema/v1.1";
    public File xsdtest;

    public boolean validate(StreamSource xmlSource) {   
        SchemaFactory factory = SchemaFactory.newInstance(language);
        Schema schema = factory.newSchema(new StreamSource(xsdtest));
        Validator newValidator = schema.newValidator();

        try {
            validator.validate(xmlSource);
        } catch (IOException | SAXException ex) {
            LOGGER.log(Level.SEVERE, ex.getMessage());
        }
        return true;
    }
}

newValidator.validate()触发断言规则。

如果不满足规则,此断言规则将导致异常,抛出“cvc-assertion.3.13.4.1:断言评估....没有成功”,其中...是来自xsd的断言规则

以上按预期工作,将annuityPercentage设置为0将导致断言错误,任何高于0的值都不会。

但是我无法将常见类型移动到第二个xsd,并结合断言,因为现在断言规则总是被触发,也是正确的输入。

如果我删除了断言,则验证有效,但只验证minOccurs等基本规则。

在下面的代码中,CoverType被移动到单独的xsd文件CommonTypes.xsd。 我还将类型名称从CoverType更改为CovertypeType。

这是CommonTypes.xsd的内容,现在持有CovertypeType:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema targetNamespace="https://mywebsite.com/xsd/CommonTypes"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
            elementFormDefault="qualified" >
    <xsd:simpleType name="CovertypeType">
        <xsd:restriction base="xsd:string">
            <xsd:enumeration value="LEVEL"/>
            <xsd:enumeration value="ANNUITY"/>
            <xsd:enumeration value="LINEAIR"/>
        </xsd:restriction>
    </xsd:simpleType>
</xsd:schema>

这是ApplicationForm.xsd的新内容:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:cmn="https://mywebsite.com/xsd/CommonTypes"
            xmlns:xerces="http://xerces.apache.org"
            xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="https://mywebsite.com/xsd/ApplicationForm"
            elementFormDefault="qualified">
    <xsd:import schemaLocation="CommonTypes.xsd"
                namespace="https://mywebsite.com/xsd/CommonTypes" />
    <xsd:element name="policy" vc:minVersion="1.1">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="surname" type="xsd:string" minOccurs="1" />
                <xsd:element name="coverType" type="cmn:CovertypeType" minOccurs="1" />
                <xsd:element name="annuityPercentage" type="xsd:decimal" minOccurs="0" maxOccurs="unbounded"/>
            </xsd:sequence>
            <xsd:assert test="(coverType = 'LEVEL' or coverType = 'LINEAIR') or (annuityPercentage > 0) "/>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

我更改了测试xml以匹配新的ApplicationForm.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<afo:policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="https://mywebsite.com/xsd/ApplicationForm ApplicationForm.xsd"
        xmlns:afo="https://mywebsite.com/xsd/ApplicationForm" 
        xmlns:cmn="https://mywebsite.com/xsd/CommonTypes" >
    <afo:surname>test</afo:surname>
    <afo:coverType>ANNUITY</afo:coverType>
    <afo:annuityPercentage>1</afo:annuityPercentage>
</afo:policy>

我还更新了Java代码,以便使用URL中的xsd而不是文件:

public class ValidationHandler {
    static final String language = "http://www.w3.org/XML/XMLSchema/v1.1";

    public boolean validate(StreamSource xmlSource) {   
        SchemaFactory factory = SchemaFactory.newInstance(language);
        Schema schema = factory.newSchema(new URL("https://mywebsite.com/xsd/ApplicationFormOrv.xsd"));
        Validator newValidator = schema.newValidator();

        try {
            validator.validate(xmlSource);
        } catch (IOException | SAXException ex) {
            LOGGER.log(Level.SEVERE, ex.getMessage());
        }
        return true;
    }
}

任何提示/帮助将不胜感激!

0 个答案:

没有答案