Почему мой 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>
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>
Похоже, что в старой версии PHP была ошибка, которая с тех пор была исправлена. Эти экземпляры элементов явно недопустимы.
Мой предпочтительный способ определения простого типа для элементов, которые могут содержать целое число или ничего, - это определить тип списка с помощью ItemType=целое число, minLength=0, maxLength=1. Основная причина, по которой я предпочитаю этот тип объединения, заключается в том, что он лучше работает в XSLT и XQuery с поддержкой схемы; он также может лучше работать для некоторых продуктов привязки данных.
Данные должны быть целым числом между значениями, указанными в XSD. Вы передаете пустое значение. По крайней мере... так это должно быть проверено. Я думаю, что XML, который вы передаете, не должен проверяться в соответствии со схемой.
Возможно, версия синтаксического анализатора XML отличается от версий PHP, и более старая версия была прощающей. В любом случае, я прочитал эту схему так: два поля должны присутствовать ровно один раз и должны содержать целое число между x и y (где x и y указаны в minInclusive и maxInclusive). Пустое значение должно не пройти проверку.