Cosa fa elementFormDefault in XSD?


88

Cosa fa elementFormDefaulte quando dovrebbe essere usato?

Quindi ho trovato alcune definizioni per i elementFormDefaultvalori:

qualificato : gli elementi e gli attributi si trovano nel targetNamespace dello schema

non qualificato : elementi e attributi non hanno uno spazio dei nomi

Quindi da quella definizione penserei che se uno schema è impostato su qualificato, perché è necessario anteporre al tipo lo spazio dei nomi? E quali sono gli scenari in cui vorresti impostare uno non qualificato per quella materia? Ho provato a usare Google, ma tutto quello che ho ottenuto sono state un paio di pagine W3C che erano estremamente difficili da capire.

Questo è il file con cui sto lavorando in questo momento, perché devo dichiarare il tipo come target:TypeAssignmentsquando dichiaro targetNamespacecome lo stesso di xmlns:target?

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:target="http://www.levijackson.net/web340/ns"
        targetNamespace="http://www.levijackson.net/web340/ns" 
        elementFormDefault="qualified">
  <element name="assignments">
    <complexType>
      <sequence>
        <element name="assignments" type="target:TypeAssignments"
                 minOccurs="1" maxOccurs="unbounded"/>
      </sequence>
    </complexType>
  </element>
  <complexType name="TypeAssignments">
    <sequence>
      <element name="assignment" type="target:assignmentInfo"
               minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
  </complexType>
  <complexType name="assignmentInfo">
    <sequence>
      <element name="name" type="string"/>
      <element name="page" type="target:TypePage"/>
      <element name="file" type="target:TypeFile" 
               minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
    <attribute name="id" type="string" use="required"/>
  </complexType>
  <simpleType name="TypePage">
    <restriction base="integer">
      <minInclusive value="50" />
      <maxInclusive value="498" />
    </restriction>
  </simpleType>
  <simpleType name="TypeFile">
    <restriction base="string">
      <enumeration value=".xml" />
      <enumeration value=".dtd" />
      <enumeration value=".xsd" />
    </restriction>
  </simpleType>
</schema>

Risposte:


71

ElementFormDefault non ha nulla a che fare con lo spazio dei nomi dei tipi nello schema, riguarda gli spazi dei nomi degli elementi nei documenti XML che sono conformi allo schema.

Ecco la sezione pertinente delle specifiche:

Element Declaration Schema

Component Property  {target namespace}
Representation      If form is present and its ·actual value· is qualified, 
                    or if form is absent and the ·actual value· of 
                    elementFormDefault on the <schema> ancestor is qualified, 
                    then the ·actual value· of the targetNamespace [attribute]
                    of the parent <schema> element information item, or 
                    ·absent· if there is none, otherwise ·absent·.

Ciò significa che il targetNamespace che hai dichiarato nella parte superiore dello schema si applica solo agli elementi nel documento XML conforme allo schema se elementFormDefault è "qualificato" o l'elemento è dichiarato esplicitamente nello schema come avente form = "qualificato" .

Ad esempio: se elementFormDefault non è qualificato -

<element name="name" type="string" form="qualified"></element>
<element name="page" type="target:TypePage"></element>

si aspetterà che gli elementi "name" siano nello spazio dei nomi target e gli elementi "page" nello spazio dei nomi nullo.

Per evitare di dover mettere form = "qualificato" su ogni dichiarazione di elemento, affermare elementFormDefault = "qualificato" significa che targetNamespace si applica a ogni elemento a meno che non venga sovrascritto inserendo form = "unqualified" sulla dichiarazione dell'elemento.


Sebbene questa risposta si riferisca alle specifiche, non la interpreta correttamente. Gli elementi definiti localmente si trovano ancora nel targetNamespace e non sono mai nello spazio dei nomi null. elementFormDefault è solo un interruttore che specifica se si suppone che lo spazio dei nomi li qualifichi in un'istanza.
Ihe Onwuka

1
@Ihe, non è corretto: o in ogni caso, potrebbe confondere le persone. Se una dichiarazione di un elemento locale non ha form = qualificato, la proprietà {target namespace} del componente dello schema di dichiarazione dell'elemento è "assente", e ciò significa che anche la proprietà dell'URI dello spazio dei nomi dell'istanza dell'elemento deve essere "assente.
Michael Kay

@MichaelKay Per me questo è ancora più confuso. La domanda è se nella pagina di esempio si trova nello spazio dei nomi null, perché se è il motivo per cui la specifica non dice semplicemente l'impostazione elementFormDefault = unqualified inserisce elementi definiti localmente nello spazio dei nomi null. È dire che la pagina non dovrebbe essere qualificata come spazio dei nomi in un'istanza è la stessa cosa che dire che la pagina non è in nessuno spazio dei nomi perché se è per questo che la specifica non lo dice semplicemente e perché uno schema con un targetNamespace convalida cose che non lo sono in quello spazio dei nomi?
Ihe Onwuka

1
Non "lo dice semplicemente" perché lo stai descrivendo in modo molto informale: la frase "inserire un elemento nello spazio dei nomi nullo" non sta usando la terminologia della specifica XSD; la specifica preferisce usare una terminologia molto più attenta, che spesso rende difficile la lettura ma finisce per essere molto più precisa.
Michael Kay

1
Per quanto mi riguarda, è una risposta corretta come scritta.
Michael Kay

60

Considera il seguente ComplexType AuthorTypeusato da authorelement

<xsd:complexType name="AuthorType">
  <!-- compositor goes here -->
  <xsd:sequence>
     <xsd:element name="name" type="xsd:string"/>
     <xsd:element name="phone" type="tns:Phone"/>
  </xsd:sequence>
  <xsd:attribute name="id" type="tns:AuthorId"/>
</xsd:complexType>
<xsd:element name="author" type="tns:AuthorType"/>

Se elementFormDefault="unqualified"

quindi la seguente istanza XML è valida

<x:author xmlns:x="http://example.org/publishing">
   <name>Aaron Skonnard</name>
   <phone>(801)390-4552</phone>
</x:author>

l'attributo name dell'autore è consentito senza specificare lo spazio dei nomi (non qualificato). Tutti gli elementi che fanno parte di<xsd:complexType> sono considerati locali per complexType.

Se elementFormDefault="qualified"

quindi l'istanza dovrebbe avere gli elementi locali qualificati

<x:author xmlns:x="http://example.org/publishing">
   <x:name>Aaron Skonnard</name>
   <x:phone>(801)390-4552</phone>
</x:author>

si prega di fare riferimento a questo collegamento per maggiori dettagli


55

Nuova risposta dettagliata e spiegazione a una vecchia domanda frequente ...

Risposta breve : se non aggiungi elementFormDefault="qualified"a xsd:schema, il unqualifiedvalore predefinito significa che gli elementi dichiarati localmente non si trovano in nessuno spazio dei nomi .

C'è molta confusione su cosa elementFormDefault fa, ma questo può essere chiarito rapidamente con un breve esempio ...

Versione semplificata del tuo XSD:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:target="http://www.levijackson.net/web340/ns"
        targetNamespace="http://www.levijackson.net/web340/ns">
  <element name="assignments">
    <complexType>
      <sequence>
        <element name="assignment" type="target:assignmentInfo" 
                 minOccurs="1" maxOccurs="unbounded"/>
      </sequence>
    </complexType>
  </element>
  <complexType name="assignmentInfo">
    <sequence>
      <element name="name" type="string"/>
    </sequence>
    <attribute name="id" type="string" use="required"/>
  </complexType>
</schema>

Punti chiave:

  • L' assignmentelemento è definito localmente.
  • Gli elementi definiti localmente in XSD non si trovano in nessuno spazio dei nomi per impostazione predefinita.
    • Questo perché il valore predefinito per elementFormDefaultè unqualified.
    • Questo è probabilmente un errore di progettazione dei creatori di XSD.
    • La pratica standard è usare sempre in elementFormDefault="qualified" modo che assignmentsia nello spazio dei nomi di destinazione come ci si aspetterebbe.
  • È un formattributo usato raramente nelle xs:elementdichiarazioni per le quali elementFormDefaultstabilisce valori predefiniti.

XML apparentemente valido

Questo XML sembra che dovrebbe essere valido secondo l'XSD sopra:

<assignments xmlns="http://www.levijackson.net/web340/ns"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.levijackson.net/web340/ns try.xsd">
  <assignment id="a1">
    <name>John</name>
  </assignment>
</assignments>

Avviso:

  • Lo spazio dei nomi predefinito in assignmentsluoghi assignmentse tutti i suoi discendenti nello spazio dei nomi predefinito ( http://www.levijackson.net/web340/ns).

Errore di convalida sconcertante

Nonostante sembri valido, l'XML sopra riportato produce il seguente errore di convalida confuso:

[Errore] try.xml: 4: 23: cvc-complex-type.2.4.a: È stato trovato contenuto non valido a partire dall'elemento "assegnazione". È previsto uno di "{assignment}".

Appunti:

  • Non saresti il ​​primo sviluppatore a maledire questa diagnostica che sembra dire che il contenuto non è valido perché si aspettava di trovare un assignmentelemento ma in realtà ha trovato un assignmentelemento. ( WTF )
  • Cosa significa veramente: {and }around assignmentsignifica che la convalida non era prevista assignment in nessuno spazio dei nomi qui. Sfortunatamente, quando dice di aver trovato un assignmentelemento, non menziona di averlo trovato in uno spazio dei nomi predefinito che differisce da nessuno spazio dei nomi.

Soluzione

  • La grande maggioranza del tempo: Aggiungi elementFormDefault="qualified"al xsd:schemaelemento del XSD. Ciò significa che un XML valido deve inserire elementi nello spazio dei nomi di destinazione quando dichiarato localmente nell'XSD; in caso contrario, un XML valido deve inserire elementi dichiarati localmente in nessuno spazio dei nomi.
  • Minoranza minuscola del tempo: modifica l'XML per soddisfare i requisiti dell'XSD che assignmentnon si trova in nessuno spazio dei nomi. Ciò può essere ottenuto, per esempio, aggiungendo xmlns=""alla assignmentelemento.

Riconoscimenti: grazie a Michael Kay per il feedback utile su questa risposta.


12

Importante da notare con elementFormDefault è che si applica a elementi definiti localmente , in genere elementi denominati all'interno di un blocco complexType, in contrapposizione agli elementi globali definiti al livello superiore dello schema. Con elementFormDefault = "qualificato" puoi indirizzare gli elementi locali nello schema dall'interno del documento xml utilizzando lo spazio dei nomi di destinazione dello schema come spazio dei nomi predefinito del documento.

In pratica, usa elementFormDefault = "qualificato" per poter dichiarare elementi in blocchi annidati, altrimenti dovrai dichiarare tutti gli elementi al livello più alto e farvi riferimento nello schema in elementi annidati usando l'attributo ref, ottenendo un schema molto meno compatto.

Questo bit nell'XML Schema Primer ne parla: http://www.w3.org/TR/xmlschema-0/#NS


Leggero chiarimento su quella che sembra la risposta più precisa. Con elementFormDefault = qualificato è necessario qualificare gli elementi locali nello spazio dei nomi nell'intance. Con esso impostato su non qualificato non è necessario qualificarli per lo spazio dei nomi.
Ihe Onwuka

6

elementFormDefault = "qualificato" viene utilizzato per controllare l'utilizzo degli spazi dei nomi nei documenti di istanza XML (file .xml), piuttosto che degli spazi dei nomi nel documento dello schema stesso (file .xsd).

Specificando elementFormDefault = "qualificato" si impone la dichiarazione dello spazio dei nomi da utilizzare nei documenti convalidati con questo schema.

È pratica comune specificare questo valore per dichiarare che gli elementi devono essere qualificati anziché non qualificati. Tuttavia, poiché attributeFormDefault = "unqualified" è il valore predefinito, non è necessario specificarlo nel documento dello schema, se non si desidera qualificare gli spazi dei nomi.


elementFormDefault si applica solo agli elementi definiti localmente. Gli elementi globali devono essere qualificati con spazio dei nomi indipendentemente.
Ihe Onwuka

0

Ho notato che XMLSpy (almeno la versione 2011) necessita di un targetNameSpace definito se viene utilizzato elementFormDefault = "qualificato". Altrimenti non convaliderà. Inoltre, non genererà XML con prefissi dello spazio dei nomi

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.