Как получить ограничение порядка элементов в XML-схеме? - PullRequest
4 голосов
/ 30 октября 2009

Ниже приведен фрагмент кода XML-схемы (xsd-файл), в котором я хочу, чтобы элементы NAME и ADRESS отображались в любом порядке, но всегда перед последовательностью FILM.

Итак, я пытался сделать так:

  <xs:element name="ROOM">
    <xs:complexType>
      <xs:all>
        <xs:element ref="NAME"/>
        <xs:element ref="ADRESS"/>
      </xs:all>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" ref="FILM"/>
      </xs:sequence>
      <xs:attribute name="group" type="xs:NCName"/>
      <xs:attribute name="typ" use="required" type="xs:NCName"/>
    </xs:complexType>
  </xs:element>

Я знаю, что тег <xs:all> не может быть частью элемента с другими элементами на том же дочернем уровне ... но не может найти выход ...

Есть предложения? Заранее спасибо!

Ответы [ 2 ]

3 голосов
/ 31 октября 2009

Это ограничение XSD-схемы.Я процитирую: http://www.w3.org/TR/2001/REC-xmlschema-0-20010502/, а затем прокомментирую:

Существует третий вариант ограничения элементов в группе: все элементы в группе могут появляться один раз или не появляться вообще, и они могут появляться в любом порядке.Вся группа (которая предоставляет упрощенную версию SGML & -Connector) ограничена верхним уровнем любой модели содержимого.Более того, все дочерние элементы группы должны быть отдельными элементами (без групп), и ни один элемент в модели содержимого не может появляться более одного раза, т.е. допустимые значения minOccurs и maxOccurs равны 0 и 1. Например, чтобы разрешить дочерние элементыpurchaseOrder, чтобы появиться в любом порядке, мы могли бы переопределить PurchaseOrderType как: 'All' Group

<xsd:complexType name="PurchaseOrderType">
  <xsd:all>
    <xsd:element name="shipTo" type="USAddress"/>
    <xsd:element name="billTo" type="USAddress"/>
    <xsd:element ref="comment" minOccurs="0"/>
    <xsd:element name="items"  type="Items"/>
  </xsd:all>
  <xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>

По этому определению, элемент комментария может необязательно появляться в purchaseOrder и может появляться до или после любого shipTo,элементы billTo и items, но могут появиться только один раз.Более того, условия группы all не позволяют нам объявлять элемент, такой как комментарий, вне группы как средство, позволяющее ему появляться более одного раза.Схема XML предусматривает, что вся группа должна отображаться как единственный дочерний элемент в верхней части модели содержимого.Другими словами, следующее недопустимо: Недопустимый пример с группой «Все»

<xsd:complexType name="PurchaseOrderType">
 <xsd:sequence>
  <xsd:all>
    <xsd:element name="shipTo" type="USAddress"/>
    <xsd:element name="billTo" type="USAddress"/>
    <xsd:element name="items"  type="Items"/>
  </xsd:all>
  <xsd:sequence>
   <xsd:element ref="comment" minOccurs="0" maxOccurs="unbounded"/>
  </xsd:sequence>
 </xsd:sequence>
 <xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>

Мои воспоминания о дискуссиях того времени заключались в том, что xsd:all будет слишком сложным для моделирования, если оно будет менее ограниченным, чем это.Это скоро распространяется на недетерминированные модели анализа.Таким образом, ограничение было либо 0, либо 1 и ни для каких братьев и сестер.

У SGML была более мощная модель, использующая разъем &, но не все системы реализовали ее.

EDIT Если вы хотите проверить свой XML на этом уровне, вы можете использовать Schematron в качестве второго валидатора после схемы.Он основан на XSLT, и этот тип ограничений легче выразить.

1 голос
/ 30 октября 2009

Хорошо, похоже, я нашел путь в конце концов:

  <xs:element name="ROOM">
    <xs:complexType>

      <xs:choice>
        <xs:sequence>
          <xs:element ref="NAME"/>
          <xs:element ref="ADRESS"/>
          <xs:element maxOccurs="unbounded" ref="FILM"/>
        </xs:sequence>
        <xs:sequence>
          <xs:element ref="ADRESS"/>
          <xs:element ref="NAME"/>
          <xs:element maxOccurs="unbounded" ref="FILM"/>
        </xs:sequence>
      </xs:choice>

      <xs:attribute name="group" type="xs:NCName"/>
      <xs:attribute name="typ" use="required" type="xs:NCName"/>
    </xs:complexType>
  </xs:element>

Но я предполагаю, что это не очень оптимизировано, учитывая, что если вы хотите сделать это с 10 элементами, вы должны указать все перестановки ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...