Средний путь между XSD all и последовательностью XSD - PullRequest
25 голосов
/ 08 мая 2009

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

<xs:all>
  <xs:element name="name" blabla />
  <xs:element name="email" blabla />
  <xs:element name="nationality" minOccurs="1" maxOccurs="unbounded" />
</xs:all>

Однако это незаконно. Очевидно, что элементы внутри «Все» могут встречаться только один раз (или не появляться вообще). Я мог бы исправить это, изменив Все на Последовательность, но тогда людям пришлось бы вводить свойства в точном порядке, который меня на самом деле не волнует.

Есть ли комбинация этих двух доступных? Не согласно http://www.w3schools.com/Schema/schema_complex_indicators.asp,, но, возможно, оно скрыто (или мои неопытные глаза этого не видят).

По интуиции я тоже попробовал:

<xs:all>
  <xs:element name="name" blabla />
  <xs:element name="email" blabla />
  <xs:sequence>
    <xs:element name="nationality" minOccurs="1" maxOccurs="unbounded" />
  </xs:sequence>
</xs:all>

Но это, к сожалению, неверно.


Вот текущий, настоящий, кусок XSD:

  <!-- user -->
  <xs:complexType name="user">
    <xs:sequence>
      <xs:element name="firstname" type="xs:string" minOccurs="1" maxOccurs="1" />
      <xs:element name="appendix" type="xs:string" minOccurs="0" maxOccurs="1" />
      <xs:element name="lastname" type="xs:string" minOccurs="1" maxOccurs="1" />
      <xs:element name="address" type="xs:string" minOccurs="1" maxOccurs="1" />
      <xs:element name="zipcode" type="xs:string" minOccurs="1" maxOccurs="1" />
      <xs:element name="city" type="xs:string" minOccurs="1" maxOccurs="1"/>
      <xs:element name="username" type="xs:string" minOccurs="1" maxOccurs="1"/>
      <xs:element name="email" type="xs:string" minOccurs="1" maxOccurs="1"/>
      <xs:element name="country" type="country" minOccurs="1" maxOccurs="1"/>
      <xs:element name="nationality" type="xs:string" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

Ответы [ 7 ]

21 голосов
/ 08 мая 2009

Не могли бы вы просто превратить свою "национальную" вещь в ее собственный complexType, а затем использовать этот новый сложный тип внутри xs: all?

<xs:complexType name="NationalityType">
  <xs:sequence>   
    <xs:element name="nationality" minOccurs="1" maxOccurs="unbounded" />
  </xs:sequence>
</xs:complexType>

<xs:all>
  <xs:element name="name" blabla />
  <xs:element name="email" blabla />
  <xs:element name="nationalities" type="NationalityType" />
</xs:all>

У меня нет ничего под рукой, чтобы проверить это, так что это на самом деле просто не в моей голове ..... попробуй!

РЕДАКТИРОВАТЬ: протестировано на данный момент - оно работает, единственная незначительная цена, которую нужно заплатить, это то, что ваш XML должен выглядеть примерно так:

<....>
  <email>......</email>
  <nationalities>
    <nationality>ABC</nationality>
    <nationality>CDE</nationality>
  </nationalities>
  <name>.....</name>
</.....>

Таким образом, вы получите дополнительный узел, который будет содержать произвольный длинный список <nationality> элементов.

Марк

20 голосов
/ 28 ноября 2011

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

<?xml version='1.0' encoding='UTF-8'?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name='user'>
    <xs:complexType>
      <xs:sequence minOccurs="0" maxOccurs="unbounded">
        <xs:choice>
          <xs:element name="name" type="xs:string" />
          <xs:element name="email" type="xs:string" />
          <xs:element name="nationality" />
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Это позволяет вам иметь любое имя, адрес электронной почты и национальность в любом порядке.

7 голосов
/ 03 декабря 2009

Я думаю, что то, что вы ищете, противоречит цели XML. Было бы странно иметь правильный XML-фрагмент, подобный этому:

<user>
  <nationality/>
  <name/>
  <nationality/>
  <email/>
  <nationality/>
</user>

Похоже, вы спрашиваете что-то вроде того, что предложил marc_s:

<user>
  <name/>
  <email/>
  <nationality/>
  <nationality/>
  <nationality/>
<user>

, который нужно вставить в:

<user>
  <name/>
  <email/>
  <nationalities>
     <nationality/>
     <nationality/>
     <nationality/>
  </nationalities>
<user>
3 голосов
/ 09 мая 2009

Ваш код должен быть действительным в XSD 1.1. Для XSD 1.0 вы должны найти обходной путь.

1 голос
/ 12 августа 2011

Для XSD 1.0 действует предложение от леппи.

XSD

<?xml version='1.0' encoding='UTF-8'?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name='user'>
    <xs:complexType>
      <xs:sequence>
        <xs:element name="name" type="xs:string" />
        <xs:element name="email" type="xs:string" />
        <xs:choice minOccurs='0' maxOccurs='unbounded'>
          <xs:element name="nationality" />
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Пример XML-документа, который проверяется по схеме

<user>
  <name>Name</name>
  <email>name@name.com</email>
  <nationality>Italian</nationality>
  <nationality>Japanese</nationality>
  <nationality>Alien</nationality>
</user>

И подтверждение, например используя xmllint

xmllint --noout --schema test.xsd test.xml
test.xml validate
0 голосов
/ 08 мая 2009

xs:choice не будет работать? Если нет, просто оберните это в последовательности или наоборот.

0 голосов
/ 08 мая 2009

Или, поскольку «USER» будет настроен с несколькими дочерними элементами, почему бы не настроить его как сложный тип? Нечто подобное должно работать.

<xs:complexType>
  <xs:sequence>
    <xs:element name="Name" type="xs:string" />
    <xs:element name="Password" type="xs:string" />
    <xs:element minOccurs="1" maxOccurs="unbounded" name="Nationality" type="xs:string" />
  </xs:sequence>
</xs:complexType>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...