2010-04-22 13 views
15

Come posso progettare il mio xsd per ignorare la sequenza di elementi?Ignora ordine di elementi usando xs: estensione

<root> <a/> <b/> </root> 

<root> <b/> <a/> </root> 

devo usare extension per ragioni di generazione di codice, così ho provato quanto segue usando all:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema targetNamespace="http://www.example.com/test" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      xmlns:t="http://www.example.com/test" > 

    <xs:complexType name="BaseType"> 
     <xs:all> 
      <xs:element name="a" type="xs:string" /> 
     </xs:all> 
    </xs:complexType> 

    <xs:complexType name="ExtendedType"> 
     <xs:complexContent> 
      <xs:extension base="t:BaseType"> 
       <xs:all> <!-- ERROR --> 
        <xs:element name="b" type="xs:string" /> 
       </xs:all> 
      </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 

    <xs:element name="root" type="t:ExtendedType"></xs:element> 
</xs:schema> 

Questo xsd non è valido comunque, th e seguente errore viene riportato in <!-- ERROR -->:

cos-all-limited.1.2: Un gruppo tutto modello deve apparire in una particella con {verifica min} = {verifica max} = 1, e quella particella deve essere parte di una coppia che costituisce il {tipo di contenuto} di una definizione di tipo complessa.

documentazione di cos-all-limited.1.2 dice:

1,2 il {termine} proprietà di una particella con {verifica max} = 1 che è parte di una coppia che costituisce il {tipo di contenuto} di tipo complesso definizione.

Io non capisco questo (né XSD né inglese madrelingua :)).


sto facendo la cosa sbagliata, sto facendo la cosa giusta sbagliata, o non c'è un modo per raggiungere questo obiettivo?

risposta

6

MAJOR EDIT Originariamente mi mancava il requisito che è necessario utilizzare xsd:extension. Notare che xsd:extension funziona come se esistesse xsd:sequence con il contenuto del tipo di base seguito dal contenuto del tipo esteso. Come XML Schema Primer dice:

Quando un tipo complesso è derivato da estensione, il suo contenuto efficace modello di è il modello di contenuto del tipo di base più il modello di contenuto specificato nel il tipo di derivazione. Inoltre, i due modelli di contenuto vengono considerati come due figli di un gruppo sequenziale.

Pertanto, sembra che l'unico modo per fare questo lavoro è di avere un tipo di base vuoto e memorizzare l'intera alternativo nel tipo esteso, o viceversa (tutto in base ed estensione vuoto).Come questo:

<xsd:complexType name="ExtendedType"> 
    <xsd:complexContent> 
     <xsd:extension base="BaseType"> 
     <xsd:choice> 
      <xsd:sequence> 
       <xsd:element name="a" type="xsd:string"/> 
       <xsd:element name="b" type="xsd:string"/> 
      </xsd:sequence> 
      <xsd:sequence> 
       <xsd:element name="b" type="xsd:string"/> 
       <xsd:element name="a" type="xsd:string"/> 
      </xsd:sequence> 
     </xsd:choice> 
     </xsd:extension> 
    </xsd:complexContent> 
</xsd:complexType> 

<xsd:complexType name="BaseType"/> 

<xsd:element name="root" type="ExtendedType"/> 
+0

@Peter Destra, ho perso quella parte. Ecco un aggiornamento. – Bolo

+0

Grazie per il tuo aggiornamento. Sfortunatamente ho bisogno di definire alcuni elementi nel tipo base e alcuni nell'estensione, quindi a meno che non ci sia un altro modo, gli elementi del tipo esteso dovranno sempre essere posizionati dopo gli elementi del tipo base ... –

+0

@Peter In tal caso, poiché "due modelli di contenuto sono trattati come due figli di un gruppo sequenziale", non c'è modo (per quanto posso vedere) di ignorare la sequenza. – Bolo

-3

<xs:complexType name="BaseType"> 
    <xs:sequence> 
     <xs:element name="a" type="xs:string" /> 
    </xs:sequence> 
</xs:complexType> 

<xs:complexType name="ExtendedType"> 
    <xs:complexContent> 
     <xs:extension base="t:BaseType"> 
      <xs:sequence> 
       <xs:element name="b" type="xs:string" /> 
      </xs:sequence> 
     </xs:extension> 
    </xs:complexContent> 
</xs:complexType> 

<xs:element name="root" type="t:ExtendedType"></xs:element> 

+0

@Ruslan: hai provato questo? Impone la sequenza di 'a' prima di' b', quindi in realtà non mi aiuta ... –

6

Ecco la spiegazione della restrizione: http://marc.info/?l=xerces-j-user&m=118712527901786&w=4

L'unica estensione si può fare per tipo complesso con un "tutto" il modello è aggiungere alcuni attributi. Non puoi estendere con nuovi elementi.

Nel mio caso ho fatto qualcosa di simile:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema targetNamespace="http://www.example.com/test" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      xmlns:t="http://www.example.com/test" > 

    <xs:complexType name="BaseType"> 
     <xs:all> 
      <xs:element name="a" type="xs:string" /> 
     </xs:all> 
    </xs:complexType> 

    <xs:complexType name="ExtendedType"> 
     <xs:all> 
      <xs:element name="a" type="xs:string" /> <!-- copy/paste from BaseType --> 
      <xs:element name="b" type="xs:string" /> 
     </xs:all> 
    </xs:complexType> 

    <xs:element name="root" type="t:ExtendedType"></xs:element> 
</xs:schema> 
Problemi correlati