2009-04-07 9 views
1

J'ai toujours considéré que XMLSchemas et DTD étaient équivalentes, mais que ce dernier est plus lourd à utiliser lors de la modélisation de relations complexes (comme l'héritage).Equivalence des DTD et des XMLSchemas

Récemment je voulais construire un schéma pour valider les documents qui ont une structure comme celle-ci:

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

Les éléments à l'intérieur < données> peuvent apparaître dans l'ordre et chacun de cardinalité 0 .. * utilisant XMLSchema, si je définis un type complexe en utilisant < xs: all> Je peux avoir les éléments en désordre mais la cardinalité maximum est 1. < xs: sequence> et < xs: choice> sont les autres candidats évidents mais ils sont plus restrictive que ce que je veux.

Je remarquai alors qu'une DTD semble être en mesure d'y parvenir comme ceci:

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

Est-il possible de construire un schéma équivalent ou dois-je utiliser ici DTDs?

Répondre

0

Je pensais que je reviens à ce que la réponse précédente est incorrecte. En effet, on peut résoudre le problème original en utilisant XML Schema.

L'approche correcte est de définir un élément de groupe qui contient un choix entre toutes les différentes options (ints, floats, tableaux) et chacun a une cardinalité 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> 

A partir de là, il reste à faire référence au groupe dans une définition complexType et définir la cardinalité du groupe comme 0 .. *

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

et le tour est joué. un peu verbeux (en particulier par rapport à la syntaxe de RelaxNG) mais l'avantage est que XML Schema est bien mieux supporté. J'avais conçu un analyseur basé sur RelaxNG pour résoudre le problème original mais les validateurs disponibles (comme JING) sont plutôt plus maladroits que l'utilisation des outils basés sur XML Schema fournis avec Java et al.

1

Ce n'est possible que par XSD si vous conservez l'ordre de vos éléments (vous pouvez donc utiliser un xs: sequence). Je veux dire, un flotteur toujours venir après un tableau (le cas échéant), et et un int viendra toujours après un flotteur (le cas échéant), en tenant compte du fait que vous pouvez répéter autant de ocurreces que vous souhaitez de chaque type (ou les omettre complètement).

La raison en est que XSD xs: tous type complexe ne supporte pas attribut pour sans bornes l'un de ses types de contenu (éléments, d'autres types de groupes imbriqués, etc.). D'autres schémas plus "détendus" vous permettront de le faire, tels que DTD, comme vous le dites, ou RelaxNG par exemple.

Voici un XSD exemple qui correspond à votre fichier 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

Merci Fernando. Je ne peux pas supposer une séquence particulière en raison de la façon dont les données seront générées, donc je vais regarder quelques alternatives. Je ne veux pas utiliser de DTD car je ne peux pas valider les données de l'élément, sauf de manière très lâche. Cela laisse RelaxNG * doigts croisés *. – Daniel

Questions connexes