使用 xsd 1.1 断言进行范围检查



我接到了一个任务,即生成一个XSD文件,用于验证xml文件中的渔业数据。所涉及的数据列出了钓鱼旅行中钓鱼期间捕获的所有鱼(包括所有详细信息(,例如species_code、长度、性别等。验证的第一部分是检查species_code是否有效,我已经通过在枚举中列出所有有效sp_code并根据此列表检查sp_code来完成此检查。 下面是来自 xml 文件的捕获

<CATCH>
<CATCH_ID>1</CATCH_ID>
<CATCH_DATE>2017-06-02T05:27:49Z</CATCH_DATE>
<SP_CODE>ALB</SP_CODE>
<LEN>103</LEN>
<SEX_CODE>U</SEX_CODE>
<LAT>-2033.126</LAT>
<LON>+17602.598</LON>
<CATCH>

我设法做的第一部分是检查输入SP_CODE是否有效:

<xs:element name="CATCH" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="SP_CODE" minOccurs="0">
<xs:simpleType>
<xs:restriction base="SP_ENUM">
<xs:assertion/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="LEN" type="xs:integer" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="SP_ENUM">
<xs:restriction base="xs:string">
<xs:enumeration value="ALB"/>
<xs:enumeration value="ALO"/>
<xs:enumeration value="ALX"/>
<xs:enumeration value="BAR"/>
<xs:enumeration value="BET"/>
</xs:restriction>
</xs:simpleType>

但是,还有第二部分有点搞砸了我的头脑(此 xsd 验证的新手。问题取决于species_code,有一个长度范围,例如sp_code是 BET--对于大眼金枪鱼,那么长度应该在 50-200 厘米范围内,否则如果SP_CODE是 ALB--对于长鳍金枪鱼,那么长度应该在 50-140 厘米范围内,等等。这是我想在我的 xsd 中测试的简单业务规则。我正在做一些搜索,并向我展示 xsd 1.1 断言是一种方式,但不清楚如何使用它来解决这个问题。有什么建议吗?

您可以选择编写一个复杂的断言或许多小断言(每个断言都必须为真(。我会使用后一种方法,因为如果断言失败,更容易看到出了什么问题。典型的断言可能是

<xs:assert test="if (SP_CODE eq 'ALB') then (LEN ge 50) else true()"/>
<xs:assert test="if (SP_CODE eq 'ALB') then (LEN le 250) else true()"/>

这些元素应该在<xs:complexType>之后显示为<xs:element name="CATCH">的子元素。它们不属于SP_CODE,就像在您的样本中一样,因为它们不会影响什么是有效的SP_CODE,而只影响什么是有效的 CATCH。

else true()是满足 XPath 语法规则所需的繁琐样板。它基本上说,如果"if"条件不适用,那么断言不施加任何约束。

最新更新