【问题标题】:XML date validation using XSD assertion with Saxon.Api (.NET version)使用带有 Saxon.Api(.NET 版本)的 XSD 断言的 XML 日期验证
【发布时间】:2020-07-08 17:27:30
【问题描述】:

验证规则:当 EndDate 不为 null/空时,EndDate 应该大于 StartDate。 我在最后一次输入雇主时遇到错误,而我预计不会。我做错了吗?

XML

<Employers>
    <Employer>
      <StartDate>2020-01-01</StartDate>
      <EndDate></EndDate>
  </Employer>
  <Employer>
      <StartDate>2020-01-01</StartDate>
      <EndDate>2021-01-01</EndDate>
  </Employer>
</Employers>

XSD

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
   <xs:element name="Employers">
      <xs:complexType>
         <xs:sequence>
            <xs:element name="Employer" maxOccurs="unbounded">
               <xs:complexType>
                  <xs:sequence>
                        <xs:element name="StartDate" type="xs:date"></xs:element>
                            <xs:element name="EndDate" minOccurs="0">
                                <xs:simpleType>
                                     <xs:union>
                                    <xs:simpleType>
                                        <xs:restriction base="xs:string">
                                            <xs:minLength value="0" />
                                            <xs:maxLength value="0" />
                                        </xs:restriction>
                                    </xs:simpleType>
                                    <xs:simpleType>
                                        <xs:restriction base="xs:date">
                                        </xs:restriction>
                                    </xs:simpleType>
                                </xs:union>
                                </xs:simpleType>
                            </xs:element>
                        </xs:sequence>
                        <xs:assert test="if (./EndDate eq '') then true() else ./EndDate gt ./StartDate" xmlns:saxon="http://saxon.sf.net/" saxon:message="Error: errors"/>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema> 

【问题讨论】:

    标签: .net xml xsd saxon


    【解决方案1】:

    做一个小修正:
    因为您的 EndDate 类型是 xs:stringxs:date 的联合,所以类型可能是其中一种,如果比较的类型不匹配,它将失败 - 产生错误。可以通过将其转换为通用类型来修复此错误 - 这里我选择了xs:string。现在它会根据空字符串而不是 xs:date 本身检查日期的 xs:string 版本。

    所以把你的断言改成

    <xs:assert test="if (xs:string(EndDate) eq '') then true() else EndDate gt StartDate" xmlns:saxon="http://saxon.sf.net/" saxon:message="Error: errors" />
    

    现在它应该可以正常工作了。

    【讨论】:

      【解决方案2】:

      在定义可以是日期或空的元素时,我的偏好是使用 minLength=0、maxLength=1 的列表类型,而不是使用 xs:date 和零长度字符串的并集。我认为这更好地反映了“空”案例代表“无日期”的语义,而不是存在且具有除日期以外的类型的东西。输入的值总是xs:date?,这更好地适应了XPath 比较运算符的语义:空的情况现在是一个空序列,而不是一个字符串。如果你这样把EndDate做成list类型,那么比较就变成了

      empty(EndDate) or EndDate gt StartDate
      

      或者,如果您愿意,

      not(EndDate le StartDate)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多