Сейчас у меня есть рабочий XSD для:

<Portal layout="blah" />

Теперь я хочу расширить систему, поэтому я могу это сделать (но я также хочу поддерживать СТАРЫЙ стиль выше):

<Portal>
  <layout xsi:type="type1">
    <attribute ... />
    <attribute ... />
    <attribute ... />
  </layout>
</Portal>

<Portal>
  <layout xsi:type="type2">
    <otherAttribute ... />
    <someVal ... />
  </layout>
</Portal>

Поэтому я хочу, чтобы устаревшая простая строка, а затем более сложный тип включали тип xsi... Вы не должны смешивать их.

Это возможно?

2
SledgeHammer 15 Июл 2015 в 02:25

2 ответа

Я пытаюсь упростить проблему следующим образом: элемент Portal допускает более сложные комбинации, такие как выражение layout в виде атрибута или выражение в виде элемента. Итак, у нас есть следующие модели контента:

<Portal layout="blah" />

<Portal>
    <layout >
       <attribute ... />
       <attribute ... />
    </layout>
</Portal>

Для этого вы определите базовый тип, который является надмножеством обеих моделей контента:

<xs:complexType name="PortalBase" abstract="true">
        <xs:sequence>
            <xs:element ref="layout" minOccurs="0"/>
        </xs:sequence>
       <xs:attribute ref="layout"/>
    </xs:complexType>

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

<xs:complexType name="layoutAttribute">
        <xs:complexContent>
            <xs:restriction base="PortalBase">
                <xs:attribute ref="layout" use="required"/> 
            </xs:restriction>
        </xs:complexContent>
    </xs:complexType>

Мы можем вывести второй тип, который принимает только layout, определенный как элемент:

<xs:complexType name="layoutElement">
        <xs:complexContent>
            <xs:restriction base="PortalBase">
                <xs:sequence>
                    <xs:element ref="layout" minOccurs="1"/>
                </xs:sequence>
                <xs:attribute  ref="layout" use="prohibited"/>
            </xs:restriction>
        </xs:complexContent>

    </xs:complexType>

Мы можем использовать их в схеме, чтобы определить элемент portal как имеющий тип PortalBase:

  <xs:element name="portal" type="PortalBase"/>

Затем мы можем использовать их в документах экземпляра, чтобы объявить, какой производный тип мы используем:

<portal xsi:type= "layoutElement">
    <layout attr1=""/>
</portal>

Или же:

<portal xsi:type= "layoutAttribute" layout="blah"/>
1
Kachna 15 Июл 2015 в 21:54
Спасибо! Я буду играть с этим!
 – 
SledgeHammer
16 Июл 2015 в 06:04

Этого можно добиться, используя атрибут Mixed Content в определении типа портала.

Что-то типа:

<xs:element name="Portal">
  <xs:complexType mixed="true"> <!-- this allows "old school" text content -->
    <xs:choice minOccurs="0"> <!-- this allows use of one of the two layout types, or none at all. -->
      <xs:element name="Layout1" type="layout1" />
      <xs:element name="Layout2" type="layout2" />
    </xs:sequence>
  </xs:complexType>
</xs:element>

Ограничение здесь заключается в том, что вы не можете определять элементы разных типов с одним и тем же именем в одном и том же элементе «группировки» (в данном случае элемент выбора)

0
tom redfern 15 Июл 2015 в 14:15