Эквивалентность DTD и XMLSchemas - PullRequest
1 голос
/ 07 апреля 2009

Я всегда понимал, что XMLSchemas и DTD эквивалентны, но последние более громоздки для использования при моделировании сложных отношений (например, наследования).

Недавно я хотел создать схему для проверки документов, имеющих такую ​​структуру:

<data>
 <array>
   <int></int>
   <int></int>
 </array>
 </array>
   <float></float>
   <float></float>
 </array>
 <int><int>
 <float></float>
</data>

Элементы внутри могут появляться в любом порядке, и каждый имеет кардинальное число 0 .. * Используя XMLSchema, если я определяю сложный тип, используя , я могу располагать элементы не по порядку, но максимальная мощность равна 1. и - другие очевидные кандидаты, но они более строгий, чем я хочу.

Затем я заметил, что DTD, кажется, может достичь этого следующим образом:

<!ELEMENT data (array | float | int)*>

Есть ли способ построить эквивалентную схему или мне нужно использовать DTD здесь?

Ответы [ 2 ]

1 голос
/ 07 апреля 2009

Это возможно только с помощью XSD, если вы сохраняете порядок своих элементов (так что вы можете использовать xs: sequence ). Я имею в виду, что float всегда будет идти после массива (если есть), а int всегда будет идти после float (если есть), принимая во внимание, что вы можете повторять любое количество вхождений каждого типа (или полностью их исключать).

Причина в том, что XSD xs: all составной тип не поддерживает неограниченный атрибут для любого из его типов содержимого (элементов, других типов вложенных групп и т. Д.). Другая более «расслабленная» схема позволит вам сделать это, например DTD, как вы заявляете, или RelaxNG, например.

Вот пример XSD, который соответствует вашему XML-файлу:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:complexType name="arrayType">
            <xs:sequence>
                <xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
                <xs:element name="int" minOccurs="0" maxOccurs="unbounded"/>
                <xs:element name="float" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
    </xs:complexType>
    <xs:element name="data" type="arrayType"/>
</xs:schema>
0 голосов
/ 24 апреля 2009

Я думал, что вернусь к этому, так как предыдущий ответ неверен. Фактически, можно решить исходную проблему, используя XML-схему.

Правильный подход заключается в определении группового элемента, который содержит выбор между всеми различными опциями (целочисленные значения, числа с плавающей запятой, массивы), и каждый из них имеет мощность 0 .. *.

<xs:group name="dataTypesGroup">
    <xs:choice>
        <xs:element name="int" type="intType"/>
        <xs:element name="float" type="floatType"/>
        <xs:element name="array">
            <xs:complexType>
                <xs:choice>
                    <xs:element name="int" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
                    <xs:element name="float" type="xs:float" minOccurs="0" maxOccurs="unbounded"/>
                </xs:choice>
                <xs:attribute name="id" use="required"></xs:attribute>
            </xs:complexType>    
        </xs:element>
    </xs:choice>
</xs:group>

Здесь осталось сослаться на группу в определении complexType и установить мощность группы равной 0 .. *

<xs:element name="data" minOccurs="0" maxOccurs="unbounded">
    <xs:complexType>
        <xs:group ref="dataTypesGroup" minOccurs="0" maxOccurs="unbounded"/>
    </xs:complexType>
</xs:element>

и вуаля. немного многословно (особенно по сравнению с синтаксисом RelaxNG), но положительным моментом является то, что XML-схема гораздо лучше поддерживается. Я создал парсер на основе RelaxNG для решения исходной проблемы, но доступные валидаторы (например, JING) довольно неуклюжи, чем использование инструментов на основе XML-схемы, которые поставляются с Java и др.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...