Как уже упоминалось в предыдущих ответах, вы можете сделать это достаточно легко в XSD 1.0, используя атрибут xsi:type
вместо определения нового атрибута ItemType
с той же функциональностью.
XSD 1.1 включает в себяконструкция, облегчающая поддержку таких случаев, как этот, для людей, которые по какой-либо причине не хотят использовать xsi:type
таким образом: условное присвоение типа.По сути, это позволяет объявлению элемента иметь простую последовательность пар XPath / typename;Выражения XPath оцениваются последовательно, и когда значение равно true, элемент ассоциируется с соответствующим типом.В XPath есть ограничения, запрещающие заглядывать в потомки элемента или просматривать или просматривать другие части документа 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
.