Требовать, чтобы оба атрибута или ни один не присутствовали в схеме XML - PullRequest
1 голос
/ 22 января 2020

У меня есть элемент, который может выглядеть следующим образом:

<MyElement start="12.5. 2020" end="6.6 2020" info="Hello world!"/>

Но также и это:

<!-- This element still can contain useful info, but is not time-bound -->
<MyElement info="42" />

Поэтому я бы хотел задать определение узла так, чтобы либо не или оба атрибута должны присутствовать. До сих пор я только использовал документацию для документирования требования, но было бы лучше, если бы оно было непосредственно в схеме:

<xsd:complexType name="MyElement">
  <xsd:attribute name="start" type="MyDate" use="optional">
    <xs:annotation>
      <xs:documentation>end date must also be present!</xs:documentation>
    </xs:annotation>
  </xsd:attribute>
  <xsd:attribute name="end" type="MyDate" use="optional">
    <xs:annotation>
      <xs:documentation>start date must also be present!</xs:documentation>
    </xs:annotation>
  </xsd:attribute>
  <xsd:attribute name="info" type="xsd:string" use="required" />
</xsd:complexType>

1 Ответ

1 голос
/ 22 января 2020

XSD 1.0

Ваше ограничение не может быть применено только в XSD 1.0.

XSD 1.1

Ваше ограничение может быть применено в XSD 1.1 с использованием xsd:assert:

    <xsd:assert test="(@start and @end) or (not(@start) and not(@end)) "/>

Показать в контексте:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" 
  elementFormDefault="qualified"
  vc:minVersion="1.1">
  <xsd:complexType name="MyElement">
    <xsd:attribute name="start" type="xsd:string" use="optional">
      <xsd:annotation>
        <xsd:documentation>end date must also be present!</xsd:documentation>
      </xsd:annotation>
    </xsd:attribute>
    <xsd:attribute name="end" type="xsd:string" use="optional">
      <xsd:annotation>
        <xsd:documentation>start date must also be present!</xsd:documentation>
      </xsd:annotation>
    </xsd:attribute>
    <xsd:attribute name="info" type="xsd:string" use="required" />

    <xsd:assert test="(@start and @end) or (not(@start) and not(@end)) "/>

  </xsd:complexType>
  <xsd:element name="MyElement" type="MyElement"/>
</xsd:schema>
...