Подтвердить что ты не робот

Средний путь между XSD и XSD-последовательностью

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

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

Однако это незаконно. По-видимому, элементы внутри "Все" могут возникать только один раз (или совсем не). Я мог бы исправить это, изменив All to a Sequence, но тогда люди должны были бы ввести свойства в точный порядок, на который мне на самом деле все равно.

Есть ли комбинация этих двух доступных? Не в соответствии с 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>
4b9b3361

Ответ 1

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

Ответ 2

Не могли бы вы просто превратить свою "национальность" в свой собственный 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>

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

EDIT: протестировал его к настоящему времени - он работает, единственная небольшая цена, которую нужно заплатить, заключается в том, что ваш XML будет выглядеть примерно так:

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

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

Марк

Ответ 3

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

<?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>

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

Ответ 4

Я думаю, что то, что вы ищете, будет противоречить намерениям 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>

Ответ 5

Для XSD 1.0 предлагается предложение leppie.

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>[email protected]</email>
  <nationality>Italian</nationality>
  <nationality>Japanese</nationality>
  <nationality>Alien</nationality>
</user>

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

xmllint --noout --schema test.xsd test.xml
test.xml validate

Ответ 6

Или, поскольку "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>

Ответ 7

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