2016-06-01 4 views
-1

Я хочу осуществить отношения, в которых элемент «Rate» должен только существует, когда «ComponentInstId и„ComponentInstIdServ“нет, и наоборот. Как я могу это сделать в ниже XSD код?взаимоисключающие элементы в XSD

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> 
<xs:element name="Request"> 
    <xs:complexType> 
     <xs:sequence> 
      <xs:element name="Component"> 
       <xs:complexType> 
        <xs:all> 
         <xs:element name="ComponentId" nillable="false"> 
          <xs:simpleType> 
           <xs:restriction base="xs:integer"> 
            <xs:whiteSpace value="collapse"/> 
           </xs:restriction> 
          </xs:simpleType> 
         </xs:element> 
         <xs:element name="ComponentInstId" nillable="true" minOccurs="0"> 
          <xs:simpleType> 
           <xs:restriction base="xs:integer"> 
            <xs:whiteSpace value="collapse"/> 
           </xs:restriction> 
          </xs:simpleType> 
         </xs:element> 
         <xs:element name="ComponentInstIdServ" nillable="true" minOccurs="0"> 
          <xs:simpleType> 
           <xs:restriction base="xs:int"> 
            <xs:whiteSpace value="collapse"/> 
           </xs:restriction> 
          </xs:simpleType> 
         </xs:element> 
         <xs:element name="Rate" nillable="true" minOccurs="0"> 
          <xs:simpleType> 
           <xs:restriction base="xs:int"> 
            <xs:whiteSpace value="collapse"/> 
            <xs:minInclusive value="0"/> 
           </xs:restriction> 
          </xs:simpleType> 
         </xs:element> 
        </xs:all> 
       </xs:complexType> 
      </xs:element> 
     </xs:sequence> 
    </xs:complexType> 
</xs:element> 

ответ

1

Почему не эквивалент (ComponentId, (Rate | (ComponentInstId, ComponentInstIdServ?)?))?

Насколько важно, что порядок будет разрешено изменять? есть ли последовательность детей предоставить полезную информацию? Если нет, то исправить последовательность, так же, как требует HTML что head приходят до body вместо после. Если последовательность предоставляет информацию, вы можете либо размножать возможности, либо реструктурировать XML. Если вы создадите ComponentId для атрибутов Component, Id и IdServ для ComponentInst, то модель содержимого компонента может быть только (Rate | ComponentInst)?.

Вы говорите, что «Последовательность не имеет значения». Если это означает, что «последовательность не передает никакой информации», объявление следующего вида гарантирует, что вы всегда будете иметь идентификатор компонента и информацию о скорости, или информацию ComponentInst, или ни одно из них.

<xs:element name="Component"> 
    <xs:complexType> 
    <xs:choice minOccurs="0"> 
     <xs:element name="Rate" nillable="true"> 
     <xs:simpleType> 
      <xs:restriction base="xs:int"> 
      <xs:whiteSpace value="collapse"/> 
      <xs:minInclusive value="0"/> 
      </xs:restriction> 
     </xs:simpleType> 
     </ 
     <xs:element name="ComponentInst" nillable="true"> 
     <xs:complexType> 
     <xs:sequence/> 
     <xs:attribute name="Id" type="xs:int"/> 
     <xs:attribute name="IdServ" type="xs:nonNegativeInteger"/> 
     </ 
     </ 
    </ 
    <xs:attribute name="Id" type="xs:int" use="required"/> 
    </ 
</ 

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

Если на «Последовательность не имеет значения» вы имеете в виду «очень важно, чтобы все возможные последовательности из информация будет действительной ", то ваша модель контента должна быть более сложной, но это достаточно простое регулярное выражение для разработки.

[Addendum] Поскольку некоторые читатели Stack Overflow, по-видимому, не в состоянии решить проблемы, подобные этому, однако, это решение, которое позволяет использовать элементы A (думаю: ComponentId), B (думаю: Rate), C (ComponentInstId) и D (ComponentInstIdServ), чтобы появиться в любом порядке, с обязательным обязательным, остальные - дополнительным, и с ограничением, что если B не встречается, ни C, ни D не могут возникнуть.

Во-первых, давайте просто выписать выбор из всех возможных последовательностей, в компактной записи, как у ОТД или Relax NG компактный синтаксис:

((A, B?) 
| (A, C?, D?) 
| (A, D?, C?) 
| (B?, A) 
| (C?, A, D?) 
| (C?, D, A) 
| (D?, A, C?) 
| (D?, C, A) 
) 

Это (или, вернее, его XSD equivaslent) не является законным, как однако он стоит из-за правила «Уникальное атрибутирование частиц» XSD, поэтому нам нужно разделить различные левые префиксы и, как правило, сделать выражение детерминированным. Экземпляр может начинаться с A, B, C или D, поэтому сначала мы делаем четыре детерминированных выражения для этих случаев, которые затем мы можем собрать вместе.Если А первая:

(A, ((B) | (C, D?) | (D, C?))?) 

Если В первый:

(B, A?) 

Если С первым:

(C ((A, D?) | (D, A))) 

Если D является первым:

(D ((A, C?) | (C, A))) 

Или, все вместе сейчас:

((A, ((B) | (C, D?) | (D, C?))?) 
| (B, A?) 
| (C ((A, D?) | (D, A))) 
| (D ((A, C?) | (C, A))) 
) 

Или в эквиваленте XSD:

<xs:complexType name="demo"> 
    <xs:choice> 
    <!--* we can start with A *--> 
    <xs:sequence> 
     <xs:element ref="A"/> 
     <xs:choice minOccurs="0"> 
     <xs:element ref="B" minOccurs="0"/> 
     <xs:sequence> 
      <xs:element ref="C"/> 
      <xs:element ref="D" minOccurs="0"/> 
     </xs:sequence> 
     <xs:sequence> 
      <xs:element ref="D"/> 
      <xs:element ref="C" minOccurs="0"/> 
     </xs:sequence> 
     </xs:choice> 
    </xs:sequence> 
    <!--* or we can start with B *--> 
    <xs:sequence> 
     <xs:element ref="B"/> 
     <xs:element ref="A" minOccurs="0"/> 
    </xs:sequence> 
    <!--* or we can start with C *--> 
    <xs:sequence> 
     <xs:element ref="C"/> 
     <xs:choice> 
     <xs:sequence> 
      <xs:element ref="A"/> 
      <xs:element ref="D" minOccurs="0"/> 
     </xs:sequence> 
     <xs:sequence> 
      <xs:element ref="D"/> 
      <xs:element ref="A"/> 
     </xs:sequence> 
     </xs:choice> 
    </xs:sequence> 
    <!--* or we can start with D *--> 
    <xs:sequence> 
     <xs:element ref="D"/> 
     <xs:choice> 
     <xs:sequence> 
      <xs:element ref="A"/> 
      <xs:element ref="C" minOccurs="0"/> 
     </xs:sequence> 
     <xs:sequence> 
      <xs:element ref="C"/> 
      <xs:element ref="A"/> 
     </xs:sequence> 
     </xs:choice> 
    </xs:sequence> 
    </xs:choice> 
</xs:complexType> 
+0

объяснить немного больше. Последовательность не имеет значения. Модель по компоненту - это все. Невозможно выполнить компонент ComponentId. – user3366906

+0

Извините; неправильно разобрать существующую схему. Изменили ответ. –

+0

1. Элементы ComponentId, ComponentInstId, ComponentInstIdServ и Rate могут поступать в любом порядке. Здесь используется только ComponentId. Единственная требуемая зависимость заключается в том, что когда Rate является presnent, тогда ComponentInstId и ComponentInstIdServ не должны быть там. Ниже приведены примеры xmls. – user3366906