#xml #xsd #saxon
#xml #xsd #саксонский
Вопрос:
У меня есть XML, который представляет собой «композит» из фигур, которые могут содержать другие фигуры.
<?xml version="1.0" encoding="UTF-8"?>
<rootShape>
<SQUARE width="10" x="1" y="25">
<contains>
<TRIANGLE rotation="180" x="1" y="34">
<contains>
<TRIANGLE rotation="180" x="221" y="34">
<contains/>
</TRIANGLE>
<SQUARE width="10" x="1" y="25">
<contains/>
</SQUARE>
</contains>
</TRIANGLE>
</contains>
</SQUARE>
</rootShape>
У меня есть xsd, который стремится описывать, ограничивать и в конечном итоге использовать в XSLT с поддержкой схемы
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">
<xs:complexType name="SQUARETYPE">
<xs:sequence>
<xs:element name="contains">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="SQUARE">
<xs:alternative test="@kind='FILLEDSQUARETYPE'" type="FILLEDSQUARETYPE"/>
<xs:alternative test="@kind='SQUARETYPE'" type="SQUARETYPE"/>
</xs:element>
<xs:element name="TRIANGLE" type="TRIANGLETYPE"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="kind" type="xs:string"/>
<xs:attribute name="width" type="xs:int"/>
<xs:attribute name="x" type="xs:int"/>
<xs:attribute name="y" type="xs:int"/>
</xs:complexType>
<xs:complexType name="FILLEDSQUARETYPE">
<xs:sequence>
<xs:element name="contains">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="SQUARE">
<xs:alternative test="@kind='FILLEDSQUARETYPE'" type="FILLEDSQUARETYPE"/>
<xs:alternative test="@kind='SQUARETYPE'" type="SQUARETYPE"/>
</xs:element>
<xs:element name="TRIANGLE" type="TRIANGLETYPE"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="kind" type="xs:string"/>
<xs:attribute name="colour" type="xs:string"/>
<xs:attribute name="width" type="xs:int"/>
<xs:attribute name="x" type="xs:int"/>
<xs:attribute name="y" type="xs:int"/>
</xs:complexType>
<xs:complexType name="TRIANGLETYPE">
<xs:sequence>
<xs:element name="contains">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="SQUARE">
<xs:alternative test="@kind='FILLEDSQUARETYPE'" type="FILLEDSQUARETYPE"/>
<xs:alternative test="@kind='SQUARETYPE'" type="SQUARETYPE"/>
</xs:element>
<xs:element name="TRIANGLE" type="TRIANGLETYPE"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="rotation" type="xs:int"/>
<xs:attribute name="x" type="xs:int"/>
<xs:attribute name="y" type="xs:int"/>
</xs:complexType>
<xs:element name="rootShape">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="SQUARE">
<xs:alternative test="@kind='FILLEDSQUARETYPE'" type="FILLEDSQUARETYPE"/>
<xs:alternative test="@kind='SQUARETYPE'" type="SQUARETYPE"/>
</xs:element>
<xs:element name="TRIANGLE" type="TRIANGLETYPE"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
XML проверяется на соответствие XSLT, но я не уверен, почему.
суть в том, что это определение типа объединения «FILLEDSQUARETYPE», «SQUARETYPE» и «TRIANGLETYPE»
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="SQUARE">
<xs:alternative test="@kind='FILLEDSQUARETYPE'" type="FILLEDSQUARETYPE"/>
<xs:alternative test="@kind='SQUARETYPE'" type="SQUARETYPE"/>
</xs:element>
<xs:element name="TRIANGLE" type="TRIANGLETYPE"/>
</xs:choice>
который стремится определить тип элемента «SQUARE» на основе некоторого его свойства.
тем не менее, мои «КВАДРАТНЫЕ» элементы не содержат атрибута «kind», поэтому не относятся ни к одному из типов.
Итак … я немного смущен, какой тип он выводит?
Конструкция выбора налагает заданное закрытие возможностей элементов, альтернативная конструкция, похоже, не делает того же самого? Мне не нужно открытое определение, я хочу закрытое.
Мне было интересно, закроет ли это его
<xs:element name="SQUARE">
<xs:alternative test="@kind='FILLEDSQUARETYPE'" type="FILLEDSQUARETYPE"/>
<xs:alternative type="SQUARETYPE"/>
</xs:element>
т.е. квадрат является либо ЗАПОЛНЕННЫМ КВАДРАТНЫМ ТИПОМ, либо, если это не так, он ДОЛЖЕН быть КВАДРАТНЫМ ТИПОМ, поэтому, глядя на определение этого типа, он должен иметь атрибут kind, и если это не так, то это ошибка ?…но, похоже, это не то, что происходит.
Ответ №1:
Если ни одна из альтернатив не удовлетворена, то тип по умолчанию соответствует типу, объявленному в объявлении содержащего элемента, который сам по умолчанию xs:anyType
равен .
Если вы хотите, чтобы проверка завершилась неудачно, если объект @kind
не является одним из перечисленных, добавьте фасет перечисления, чтобы ограничить значение @kind
.
Комментарии:
1. ооо, вот что мне интересно, так что я не могу определить замкнутый набор альтернатив? Я могу закрыть только базовые данные? Могу ли я указать тип по умолчанию, если он не соответствует? а затем определите тип, который, как я знаю, никогда не был заселен?
2. хммм… Я также не думаю, что это сработает, я попробую и обновлю вопрос, хотя
3. да, это не работает, мой КВАДРАТНЫЙ элемент вообще не содержит какого-либо атрибута kind, поэтому проверка никогда не узнает, что «kind» должен существовать для проверки того, что в нем есть, т.Е. Проблема не в том, что значение kind неверно, проблема в том, что его вообще не существует.
4. Я обновил свой вопрос еще более простой версией, в которой, я надеюсь, я закрываю набор альтернатив, но я все еще не получаю сообщение об ошибке при проверке xml.
5. смотрите мой ответ, я сделал это, введя тип «top», но, честно говоря, мне это не нравится, я бы предпочел, чтобы «альтернатива» была больше похожа на шаблон «match» и просматривалась до тех пор, пока он что-то не найдет, и тогда я смогу решить поймать все …т.е. закрыть альтернативы.
Ответ №2:
На основе комментария Майкла Кея
решение таково
<xs:element name="SQUARE">
<xs:alternative test="@kind = 'FILLEDSQUARETYPE'" type="FILLEDSQUARETYPE"/>
<xs:alternative test="@kind = 'SQUARETYPE'" type="SQUARETYPE"/>
<xs:alternative type="xs:error"/>
</xs:element>
Который, кажется, работает для меня.