Domanda

Ho sempre ritenuto che XMLSchema e DTD siano equivalenti, ma che quest'ultimo è più complicato da utilizzare quando si modellano relazioni complesse (come l'ereditarietà).

Recentemente ho voluto creare uno schema per convalidare documenti che hanno una struttura come questa:

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

Gli elementi all'interno di <ta data> possono apparire in qualsiasi ordine e ognuno è di cardinalità 0 ..* usando xmlschema, se definisco un tipo complesso usando <xs: tutto> posso avere gli elementi fuori servizio ma la massima cardinalità è 1.< xs:sequence > e < xs:choice > sono gli altri candidati ovvi ma sono più restrittivi di quello che voglio.

Poi ho notato che un DTD sembra essere in grado di raggiungere questo obiettivo in questo modo:

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

Esiste un modo per creare uno schema equivalente o devo utilizzare DTD qui?

È stato utile?

Soluzione 2

ho pensato di tornare a questo come la risposta precedente è corretta. Infatti, si può risolvere il problema originale utilizzando XML Schema.

L'approccio corretto è quello di definire un elemento gruppo che contiene una scelta tra tutte le varie opzioni (int, galleggianti, array) e ognuno ha 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>

Da qui, rimane per fare riferimento al gruppo in una definizione complexType e impostare la cardinalità del gruppo come 0 .. *

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

et voilà. un po 'prolisso (soprattutto rispetto a sintassi di RelaxNG), ma il vantaggio è che XML Schema è molto meglio supportata. Avevo realizzato un parser basato RelaxNG per risolvere il problema originale, ma i validatori disponibili (come JING) sono un po 'più goffo che utilizzare gli strumenti basati su XML Schema forniti con Java et al.

Altri suggerimenti

È fattibile solo tramite XSD se mantieni l'ordine dei tuoi elementi (quindi puoi usare a xs:sequenza).Voglio dire, a galleggiante verrà sempre dopo un vettore (se presente) e e an int verrà sempre dopo a galleggiante (se presenti), tenendo conto che è possibile ripetere quante occorrenze si desidera di ciascun tipo (o ometterle completamente).

Il motivo è che XSD xs:tutti il tipo complesso non supporta illimitato attributo per qualsiasi tipo di contenuto (elementi, altri tipi di gruppi nidificati, ecc.).Altri schemi più "rilassati" ti permetteranno di farlo, come DTD, come dici, o RelaxNG per esempio.

Ecco un esempio XSD adatto al tuo file 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>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top