Как моделировать составной шаблон в XSD

#xml #xsd #saxon

#xml #xsd #саксонский

Вопрос:

Я пытаюсь понять, как смоделировать определенный стиль сериализации, чтобы проверить соответствие XSLT с поддержкой схемы схеме (используя Saxon).

Простым примером 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>
  

«стиль» сериализации экспортирует «тип» объекта заглавными буквами, а затем атрибуты / поля объекта в нижнем регистре. Конечные типы (например, string, int, datetime и т. Д.) Моделируются как атрибуты, В то время как ссылки на другие объекты / значения рекурсивно следуют тому же шаблону.

Итак … я могу довольно легко написать простой XSD для некоторых из них.

 <?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:element name="SQUARE">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="contains"/>
            </xs:sequence>
            <xs:attribute name="width" type="xs:int"/>
            <xs:attribute name="x" type="xs:int"/>
            <xs:attribute name="y" type="xs:int"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="TRIANGLE">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="contains"/>
            </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>
    <xs:element name="rootShape">
        <xs:complexType>
            <xs:choice>
                <xs:element ref="SQUARE"/>
                <xs:element ref="TRIANGLE"/>
            </xs:choice>
        </xs:complexType>
    </xs:element>
</xs:schema>
  

(и это успешно проверяется), но я немного застрял, как обращаться с отношением «содержит».

мощность отношения равна 0 -> неограниченная, но мощности связаны с определенным элементом, где я хочу применить мощность к различным вариантам / альтернативам (т. Е. Скорее Как тип объединения).

есть идеи? Я новичок в xsd, я просмотрел «типы» и «альтернативы», но не могу получить ничего разумного.

Ответ №1:

achchc, вы можете применить ограничения мощности к выбору …. глупый я.

 <?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:element name="SQUARE">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="contains">
                    <xs:complexType>
                        <xs:choice minOccurs="0" maxOccurs="unbounded">
                            <xs:element ref="SQUARE"/>
                            <xs:element ref="TRIANGLE"/>
                        </xs:choice>                        
                    </xs:complexType>                    
                </xs:element>
            </xs:sequence>
            <xs:attribute name="width" type="xs:int"/>
            <xs:attribute name="x" type="xs:int"/>
            <xs:attribute name="y" type="xs:int"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="TRIANGLE">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="contains">
                    <xs:complexType>
                        <xs:choice minOccurs="0" maxOccurs="unbounded">
                            <xs:element ref="SQUARE"/>
                            <xs:element ref="TRIANGLE"/>
                        </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>
    <xs:element name="rootShape">
        <xs:complexType>
            <xs:choice>
                <xs:element ref="SQUARE"/>
                <xs:element ref="TRIANGLE"/>
            </xs:choice>
        </xs:complexType>
    </xs:element>
</xs:schema>
  

Ответ №2:

Я бы сказал, что это хороший вариант использования для групп подстановки.

Определите объявление абстрактного элемента с именем SHAPE , определите SQUARE и TRIANGLE в качестве членов группы замещения SHAPE, а затем используйте SHAPE в своей модели контента везде, где вы хотите, чтобы отображался КВАДРАТ или ТРЕУГОЛЬНИК. Затем, когда вы вводите дополнительные фигуры, вам просто нужно добавить их в группу подстановки.

Комментарии:

1. итак, проблема здесь действительно в том, что эта схема будет сгенерирована (эффективно) из диаграммы ER автоматически, поэтому на самом деле меня не сильно беспокоит, насколько она лаконична, только ее семантика …. с которой я немного затрудняюсь. Существует новый вопрос, который определяет схему, но использует типы, из-за какой-то ужасной альтернативной ошибки «типа» в сериализаторе.

2. хорошей новостью является то, что как только я пойму, как сделать соотношение 0 / n альтернатив / вариантов, тогда я смогу в значительной степени делать все, что мне нужно.

3. Я думаю, что я могу взглянуть на группы замещения чуть позже, это может быть разумной оптимизацией