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

Как определить несколько элементов с тем же именем, но различный тип в элементе xsd: select?

Возможно каким-то образом определить схему xsd, которая могла бы проверить такой xml:

<item_list>
  <item ItemType="SimpleMessage" Caption="Simplest message"/>
  <item ItemType="ComplexMessage" SomeAttr="value">
    <item_data>some text</item_data>
  </item>
</item_list>

Проблема в том, что я не нашел никакой возможности определить smth вроде:

  <xsd:element name="Items">
      <xsd:complexType>
        <xsd:choice>
          <xsd:element name="item" type="SimpleMessType"/>
          <xsd:element name="item" type="ComplexMessType"/>
        </xsd:choice>
      </xsd:complexType>
  </xsd:element>

Но мне нужно проверить, что SimpleMessage не имеет дочерних элементов или дополнительных attrs: (

4b9b3361

Ответ 1

Как уже упоминалось ранее, вы можете сделать это достаточно легко в XSD 1.0, используя атрибут xsi:type вместо определения нового атрибута ItemType с той же функциональностью.

XSD 1.1 включает конструкцию, предназначенную для упрощения поддержки таких случаев, например, для людей, которые по какой-либо причине не хотят использовать xsi:type следующим образом: условное назначение типа. По сути, это позволяет объявлению элемента иметь простую последовательность пар XPath/typename; выражения XPath оцениваются последовательно, а когда оценивается значение true, элемент ассоциируется с соответствующим типом. Существуют ограничения для XPaths, которые запрещают смотреть вперед в потомки элементов или искать или удалять их в другие части документа XML (первый помогает сохранить возможность знать, как только сканирование встречает стартовый тег, который использование для проверки элемента, второе помогает сохранить без контекста проверку), поэтому по существу тесты могут быть только тестами значений атрибутов. Ваш пример можно записать так:

<xs:element name="item">
  <xs:alternative test="@ItemType='SimpleMessage'" type="SimpleMessType"/>
  <xs:alternative test="@ItemType='SimpleMessage'" type="ComplexMessType"/>
  <xs:alternative type="xs:error"/>
</xs:element>

Третий вариант гарантирует, что один из ваших ожидаемых случаев должен быть встречен, чтобы элемент был действительным. Если он здесь не указан, то, если ни одно из тестовых выражений не было истинным, ему был бы присвоен объявленный тип item, в данном случае xs:anyType.

Ответ 2

XSD явно запрещает такой случай. Вы должны изменить имена элементов, чтобы быть уникальными (или использовать xsi: type, поскольку xcut говорит, что составляет одно и то же).

Как работа, вы можете объединить определения типов SimpleMessType и ComplexMessType в один тип со смешанным = "true", а затем разобрать контент, который вы получаете в своем собственном коде после завершения обработки схемы. См. Обсуждение stackoverflow о схеме XSD для рекурсивного XML.

Ответ 3

Вы не можете сделать это, используя структуру схемы, которую вы предложили, поскольку структура нарушает правила неопределенности XML Schema.

Один потенциальный вариант для вас - определить супертип, скажем BaseElement, который является пустым, а затем подтипы, и использовать xsi:type для переопределения вместо обычного атрибута type. Более подробную информацию о том, как это работает, можно найти здесь.