XML проверка даты с использованием утверждения XSD с Saxon.Api (версия. NET) - PullRequest
0 голосов
/ 08 июля 2020

Правило проверки: EndDate должна быть больше StartDate, если EndDate не является нулевым / пустым. Я получаю сообщение об ошибке при последней записи работодателя, хотя я не ожидаю ничего. Я что-то делаю не так?

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> 

Ответы [ 2 ]

0 голосов
/ 08 июля 2020

Мое предпочтение при определении элемента, который может быть датой или пустым, - использовать тип списка с minLength = 0, maxLength = 1, а не использовать объединение xs: date и строки нулевой длины. Я думаю, что это лучше отражает семантику, согласно которой «пустой» случай представляет «нет даты», а не является чем-то существующим и имеет тип, отличный от даты. В этом случае типизированное значение всегда равно xs:date?, что лучше соответствует семантике операторов сравнения XPath: теперь пустой регистр является пустой последовательностью, а не строкой. Если вы сделаете EndDate типом списка таким образом, тогда сравнение будет

empty(EndDate) or EndDate gt StartDate

или, если хотите,

not(EndDate le StartDate)
0 голосов
/ 08 июля 2020

Сделайте одно небольшое исправление: Поскольку ваш тип EndDate представляет собой объединение xs:string и xs:date, тип может быть тем или другим, и он не будет работать, если тип сравнения не совпадает, что приведет к ошибке. Эту ошибку можно исправить, приведя ее к общему типу - здесь я выбрал xs:string. Теперь он проверяет xs:string версию вашей даты на пустую строку, а не на саму xs:date.

Так что измените ваше утверждение на

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

Теперь оно должно работать как надо.

...