xsd - Утверждение условия проверки всех потомков - PullRequest
0 голосов
/ 12 декабря 2018

У меня есть следующий xml:

<request>
  <resource>
    <regime>payed</regime>
  </resource>
  <user>
    <contract>
      <data>
        <discount>true</discount>
        <priceInPercents>0</priceInPercents>
      </data>
      <data>
        <discount>false</discount>
        <priceInPercents>20</priceInPercents>
      </data>
      <data>
        <discount>false</discount>
        <priceInPercents>0</priceInPercents>
      </data>
   </contract>
  </user>
</request>

XML следует файлу XSD, в который я хотел бы добавить условие, которое проверяет следующее: если режим «оплачен», то любойpriceInPercents не может иметь значение «0», если только элемент скидки в этом конкретном элементе данных не равен «true».(Возможные значения для режима только «оплачено» или «бесплатно»).Я пытаюсь сделать это, используя assert на уровне запроса следующим образом:

<assert test="./resource/regime/text() = 'free' 
              or ./user/contract
                 /data[discount=false]
                 /priceInPercents != 0 
              or ./user/contract
                 /data[priceInPercents = 0]
                 /discount = true "/>

В этом случае валидатор говорит, что все в порядке, потому что вторая часть условия выполняется во втором случае итретья часть заполнена в первом случае.Третий случай не соответствует ни одному из условий, но это не имеет значения, потому что assert уже нашел совпадение.Мне нужно переписать XPath, чтобы проверить шаблон для всех элементов данных, но я действительно не знаю, как это сделать.

1 Ответ

0 голосов
/ 24 декабря 2018

Если я вас правильно понял, вы должны выполнить условие, чтобы в данном запросе либо

  • resource/regime eq 'free', либо
  • для каждого элемента user/contract/dataлибо
    • priceInPercents не равен нулю, либо
    • discount eq 'true'

Одним из способов справиться с этим является обращение вспятьБулева полярность второго основного дизъюнкта и скажите «нет элемента data с обоими priceInPercents eq '0' and discount eq 'false'. Вы могли бы сказать, что так:

<assert test="./resource/regime eq 'free' 
              or not(./user/contract
                 /data[discount eq 'false' and priceInPercents eq 0])"/>

Может быть немного легче следовать, если выиспользуйте универсально выраженное выражение, которое принимает форму every ... satisfies .... В этом случае одной из возможных формулировок будет:

<assert test="./resource/regime = 'free' 
              or every $d in ./user/contract/data
                 satisfies
                 ($d/discount eq 'true' 
                 or $d/priceInPercents ne 0)"/>
...