Создание действительного XSD, открытого с использованием элементов <all>и <any> - PullRequest
7 голосов
/ 03 марта 2011

Мне нужно указать XSD для проверки документов XML. XSD будет использоваться для генерации привязок Java в JAXB. Моя проблема заключается в указании необязательных элементов, имена которых я не знаю и в которых я вообще не заинтересован в разборе.

Структура XML-документов выглядит следующим образом:

<TRADE>
  <TIME>12:12</TIME>
  <MJELLO>12345</MJELLO>
  <OPTIONAL>12:12</OPTIONAL>
  <DATE>25-10-2011</DATE>
  <HELLO>hello should be ignored</HELLO>
</TRADE>

Важно то, что:

  • Я не могу принять какой-либо порядок, и следующий экземпляр XML-документа migtht имеет теги в другом порядке
  • Меня интересует только парсинг некоторых тегов, некоторые являются обязательными, а некоторые - необязательными
  • XML-документы могут быть расширены новыми элементами, которые меня не интересуют при разборе

Структура моего XSD похожа ( не действительный xsd ):

<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <!-- *********************************************** -->
  <!-- Trade element definitions for the XML Documents -->
  <!-- *********************************************** -->

  <xs:complexType name="Trade">
    <!-- Using the all construction ensures that the order does not matter -->
    <xs:all>
      <xs:element name="DATE" type="xs:string" minOccurs="1" maxOccurs="1" />
      <xs:element name="TIME" type="xs:string" minOccurs="1" maxOccurs="1" />
      <xs:element name="OPTIONAL" type="xs:string" minOccurs="0" maxOccurs="1" />
      <xs:any minOccurs="0"/>
    </xs:all>
  </xs:complexType>

  <!-- TRADE is the mandatory top-level tag -->
  <xs:element name="TRADE" type="Trade"/>

</xs:schema>

Итак, в этом примере: DATE и TIME являются обязательными (они должны быть в XML ровно один раз), OPTIONAL может присутствовать один раз, а затем я хотел бы указать, что все остальные теги разрешены. Заказ не имеет значения.

Как мне указать действительный XSD для этого?

Ответы [ 2 ]

5 голосов
/ 03 марта 2011

Это классическая проблема с парсером.

По сути, ваш BNF:

Trade    = whatever whatever*
whatever = "DATE"  | "TIME" | anything
anything = a-z a-z*

Но это неоднозначно.Строка «DATE» может быть принята по какому-либо правилу как «DATE» и как угодно.

Так что если у вас есть

<TRADE>
  <TIME>12:12</TIME>
  <DATE>25-10-2011</DATE>
  <DATE>25-12-2011</DATE>
</TRADE>

, неясно, следует ли это принимать или нет.

Он может быть интерпретирован как один из

"TIME", "DATE", anything
anything, anything, "DATE"
anything, anything, anything
"TIME", "DATE", anything
"TIME", "DATE", "DATE"
etc.

Все сводится к следующему: если у вас есть подстановочный знак в сочетании со случайной последовательностью, вы не можете осмысленно решить, какой токен соответствует какому правилу.

Особенно не имеет смысла иметь необязательные элементы вместе с вилкой.

У вас есть два варианта:

  • использовать xs: sequence вместо xs: all
  • не используйте подстановочный знак

Насколько я понимаю, оба варианта находятся в конфликте с вашими желаниями.

Возможно, вы можете создать подстановочный знак, который соответствует всему кроме ДАТА, ВРЕМЯ и т. д.

2 голосов
/ 03 марта 2011

Трудно ли иметь привязки JAXB к вашим "известным" элементам? Если нет, вы можете просто использовать <any maxoccurs="unbounded" processContents="skip"/> в качестве xsd, а затем выбрать интересующие вас элементы из дерева DOM.

(см. здесь , как использовать JAXB без привязки данных.)

...