Определите пустые узлы xml в xsd, которые эффективно обрабатываются xjc

У нас есть xml-файл, который выглядит следующим образом. Обратите внимание, что наше приложение поддерживает все 3 из этих случаев:

<quantities>
  <quantity>8</quantity> <!-- case 1 -->
  <quantity></quantity>  <!-- case 2 -->
  <quantity/>            <!-- case 3 -->
</quantities>

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

<xs:element name="quantity" type="xs:double"/>

Но приведенный выше XSD слишком прост. Это хорошая проверка для случая 1, но она отвергает случаи 2 и 3.

Итак, мы попытались решить эту проблему с помощью пользовательского типа. Тип, который может быть как двойным, так и пустой строкой.

<xs:simpleType name="double-or-empty">
  <xs:union memberTypes="xs:double">
    <xs:simpleType>
      <xs:restriction base="xs:string">
        <xs:enumeration value=""/>
      </xs:restriction>
    </xs:simpleType>
  </xs:union>
</xs:simpleType>

<xs:element name="quantity" type="double-or-empty"/>

С функциональной точки зрения это явное улучшение, но у него есть свои недостатки. Когда мы создаем наши классы Java с помощью инструмента Java xjc.exe. Затем java будет использовать String для представления этих полей. Что очень раздражает. На самом деле мы надеялись, что это (обнуляемые) java.lang.Double полей.

Мы поэкспериментировали с идеей: создать файл xsd, который помечает это поле как nillable.

<xs:element name="quantity" type="xs:double" nillable="true"/>

Мы узнали, что это по-прежнему не поддерживает случаи 2 и 3. Это просто добавляет к нему еще 1 случай:

<quantities>
  <quantity xs:nil="true"/>
</quantities>

Однако несколько источников указывают на то, что использование xs:nil может нарушить совместимость. Затем другие источники утверждают, что мы должны использовать настраиваемый атрибут, например. <quantity null="true"/> Такого рода идеи в любом случае бесполезны, потому что они заставляют нас изменить формат XML, который мы использовали в течение длительного времени.

Итак, есть ли способ сохранить исходный формат и настроить инструмент XJC для использования здесь Doubles?


person bvdb    schedule 21.04.2016    source источник


Ответы (2)


Используйте xs:union для объединения ограничения пустой строки с другим ограничением, например xs:double:

  <xs:simpleType name="double-or-empty">
    <xs:union>
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:length value="0"/>
        </xs:restriction>
      </xs:simpleType>
      <xs:simpleType>
        <xs:restriction base="xs:double"/>
      </xs:simpleType>
    </xs:union>
  </xs:simpleType>
person kjhughes    schedule 21.04.2016
comment
Только что попробовал, но результат точно такой же, как и с двойным или пустым, указанным в моем вопросе. Я что-то упускаю ? - person bvdb; 21.04.2016

В целом это больше похоже на проблему XJC, чем на проблему XSD. Но если единственный способ найти решение — продолжать пробовать разные способы определения данных в XSD, пока не найдете тот, который XJC обрабатывает лучше, то вы можете подумать:

  • Объявление quantity со значением по умолчанию (при условии, что <quantity/> и <quantity></quantity> соответствуют значению по умолчанию, а не NULL или его логическому эквиваленту).

  • Объявление типа количества как списка значений xs:double с ограничением длины списка между нулем и единицей. (Для определения этого ограничения можно было бы использовать pattern, но я ожидаю, что фасеты minLength и maxLength здесь подойдут лучше.)

  • Объявление типа количества как союза между xs:double и некоторым типом, отличным от строки, который может принимать пустое значение. Я думаю, что мы ищем здесь базовый тип, который, по мнению XJC, не имеет лексического пространства, являющегося надмножеством лексического пространства xs:double. Возможно, это объединение xs:double и строки нулевой длины double? (Имеет ли значение порядок для XJC? Похоже, что нет, так как ваше объявление сначала ставит xs:double, а объявление kjhughes сначала ставит пустую строку; но я бы попробовал изменить порядок в его объединении на всякий случай.)

Могут быть и другие способы; это те, которые приходят на ум чаще всего (после тех, которые вы и kjhughes уже пробовали).

person C. M. Sperberg-McQueen    schedule 21.04.2016