我正在使用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;
}
}
任何提示/帮助将不胜感激!