Почему мой xml не проходит проверку с помощью XSD?


У меня небольшая проблема с тем, что пустые значения не проходят проверку на одном сервере, но это работает на всех моих других серверах. Проблема возникает в более новой версии PHP (5.3.8) и работает в немного более старой версии (5.2.4).

Вот несколько изолированных элементов, которые выходят из строя:

Ввод XML:

<clbburnfuelbias></clbburnfuelbias>
<clbburntimebias></clbburntimebias>

Проверка XSD:

  <xs:element name="clbburnfuelbias"  type="data-fuelbias"/>
  <xs:element name="clbburntimebias"  type="data-timebias"/>

  <xs:simpleType name="data-fuelbias">
    <xs:restriction base="xs:integer">
      <xs:minInclusive value="-9900"/>
      <xs:maxInclusive value="9900"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="data-timebias">
    <xs:restriction base="xs:integer">
      <xs:minInclusive value="-59"/>
      <xs:maxInclusive value="59"/>
    </xs:restriction>
  </xs:simpleType>

Ошибка:

Ошибка 1824: Элемент 'clbburnfuelbias': Значение не является допустимым значением атомарного типа "данные-топливо". Ошибка 1824: Элемент 'clbburntimebias': Значение не является допустимым значением атомарного типа
"данные-временные интервалы".

Используя одни и те же входные и XSD-файлы на разных серверах под управлением 5.2.4, я не получаю ошибок, и xml является допустимым.

Я попытался добавить к элементам minOccurs="0", я также попытался указать nullable="true", но все равно получаю ошибки.

ОБНОВЛЕНИЕ:

Похоже, что нулевые значения игнорируются на моих серверах с использованием PHP 5.2.4 и отклонен с использованием 5.3.8. Обходной путь, который я использовал, который был предложен, заключается в использовании объединения двух определений, одного для целочисленного типа и одного для нулевого значения:

XSD:

<xs:element name="clbburnfuelbias" minOccurs="0">
  <xs:simpleType>
    <xs:union memberTypes="data-fuelbias null-string"/>
  </xs:simpleType>
</xs:element>

<xs:simpleType name="data-fuelbias">
  <xs:restriction base="xs:integer">
    <xs:minInclusive value="-9900"/>
    <xs:maxInclusive value="9900"/>
  </xs:restriction>
</xs:simpleType>

<xs:simpleType name="null-string">
  <xs:restriction base="xs:string">
    <xs:length value="0"/>
  </xs:restriction>
</xs:simpleType>
Author: Ben Ashton, 2012-11-05

3 answers

Если элемент является необязательным (minOccurs="0"), его содержимое не становится подстановочным знаком. Если элемент появляется, он должен соответствовать объявленному типу.

Создание элемента с нулевым значением (nillable="true") позволяет элементу быть пустым, если он имеет атрибут xsi:nil="true", где xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance":

<clbburnfuelbias xsi:nil="true"></clbburnfuelbias>
<clbburntimebias xsi:nil="true"></clbburntimebias>

Вы также можете использовать тип объединения, который имеет то же значение только для целей проверки:

<xs:simpleType name="data-fuelbias">
  <xs:union>
    <xs:restriction base="xs:integer">
      <xs:minInclusive value="-9900"/>
      <xs:maxInclusive value="9900"/>
    </xs:restriction>
    <xs:restriction base="xs:string">
      <xs:length value="0"/>
    </xs:restriction>
  </xs:union>
</xs:simpleType>
 5
Author: acelent, 2012-11-05 18:05:24

Похоже, что в старой версии PHP была ошибка, которая с тех пор была исправлена. Эти экземпляры элементов явно недопустимы.

Мой предпочтительный способ определения простого типа для элементов, которые могут содержать целое число или ничего, - это определить тип списка с помощью ItemType=целое число, minLength=0, maxLength=1. Основная причина, по которой я предпочитаю этот тип объединения, заключается в том, что он лучше работает в XSLT и XQuery с поддержкой схемы; он также может лучше работать для некоторых продуктов привязки данных.

 3
Author: Michael Kay, 2012-11-05 19:43:57

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

Возможно, версия синтаксического анализатора XML отличается от версий PHP, и более старая версия была прощающей. В любом случае, я прочитал эту схему так: два поля должны присутствовать ровно один раз и должны содержать целое число между x и y (где x и y указаны в minInclusive и maxInclusive). Пустое значение должно не пройти проверку.

 2
Author: GarethL, 2012-11-05 18:07:47