Как определить замкнутое объединение альтернатив

#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>
  

Который, кажется, работает для меня.