Вопрос
Я всегда понимал, что XMLSchemas и DTD эквивалентны, но что последнее более громоздко использовать при моделировании сложных отношений (например, наследования).
Недавно я хотел создать схему для проверки документов, которые имеют подобную структуру:
<data>
<array>
<int></int>
<int></int>
</array>
</array>
<float></float>
<float></float>
</array>
<int><int>
<float></float>
</data>
Элементы внутри < данные > могут отображаться в любом порядке, и каждая из них имеет мощность 0..* Используя XMLSchema, если я определяю сложный тип с помощью < xs: все > У меня могут быть элементы не по порядку, но максимальная мощность равна 1.< xs:последовательность > и < xs: выбор > есть другие очевидные кандидаты, но они более ограничительные, чем то, что я хочу.
Затем я заметил, что DTD, похоже, способен достичь этого следующим образом:
<!ELEMENT data (array | float | int)*>
Есть ли какой-нибудь способ построить эквивалентную схему или я должен использовать DTDS здесь?
Решение 2
Я думал, что вернусь к этому, поскольку предыдущий ответ неверен.Фактически, исходную проблему можно решить, используя XML-схему.
Правильный подход заключается в определении элемента group, который содержит выбор между всеми различными параметрами (целые числа, значения с плавающей запятой, массивы), и каждый из них имеет мощность 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>
et voila.немного многословно (особенно по сравнению с синтаксисом RelaxNG), но положительным моментом является то, что XML-схема поддерживается намного лучше.Я создал синтаксический анализатор на основе RelaxNG для решения исходной проблемы, но доступные средства проверки (например, JING) гораздо более неуклюжи, чем использование инструментов на основе XML-схемы, которые поставляются с Java и др.
Другие советы
Это выполнимо только с помощью XSD, если вы сохраняете порядок своих элементов (так что вы можете использовать xs:последовательность).Я имею в виду, что плавать всегда будет приходить после массив (если таковые имеются), и и инт всегда будет приходить после плавать (если таковые имеются), принимая во внимание, что вы можете повторить столько ошибок, сколько пожелаете для каждого типа (или полностью их опуская).
Причина в том, что XSD xs:все сложный тип не поддерживает безграничный атрибут для любого из его типов контента (элементы, другие типы вложенных групп и т.д.).Другая, более "расслабленная" схема позволит вам сделать это, такая как 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>