Que fait elementFormDefault dans XSD?

88

Que fait elementFormDefault-il et quand doit-il être utilisé?

J'ai donc trouvé quelques définitions des elementFormDefaultvaleurs:

qualifié - les éléments et les attributs se trouvent dans le targetNamespace du schéma

non qualifié - les éléments et les attributs n'ont pas d'espace de noms

Donc, à partir de cette définition, je pense que si un schéma est défini sur qualifié, pourquoi devez-vous préfixer le type avec l'espace de noms? Et quels sont les scénarios dans lesquels vous auriez même défini un scénario non qualifié d'ailleurs? J'ai essayé Google, mais je n'ai eu que quelques pages W3C extrêmement difficiles à comprendre.

C'est le fichier avec lequel je travaille actuellement, pourquoi dois-je déclarer le type comme target:TypeAssignmentslorsque je déclare le targetNamespacecomme étant le même que 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>
Levi
la source

Réponses:

71

ElementFormDefault n'a rien à voir avec l'espace de noms des types dans le schéma, il s'agit des espaces de noms des éléments dans les documents XML qui sont conformes au schéma.

Voici la section pertinente de la spécification:

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·.

Cela signifie que le targetNamespace que vous avez déclaré en haut du schéma s'applique uniquement aux éléments du document XML conforme au schéma si elementFormDefault est "qualifié" ou si l'élément est déclaré explicitement dans le schéma comme ayant form = "qualifié" .

Par exemple: si elementFormDefault n'est pas qualifié -

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

s'attend à ce que les éléments "name" soient dans l'espace de noms targetNamespace et que les éléments "page" soient dans l'espace de noms nul.

Pour vous éviter d'avoir à mettre form = "qualifié" sur chaque déclaration d'élément, indiquer elementFormDefault = "qualifié" signifie que le targetNamespace s'applique à chaque élément à moins qu'il ne soit remplacé en mettant form = "unqualified" sur la déclaration d'élément.

Alohci
la source
Bien que cette réponse se réfère à la spécification, elle ne l'interprète pas correctement. Les éléments définis localement sont toujours dans le targetNamespace et ne sont jamais dans l'espace de noms null. elementFormDefault est juste un commutateur qui spécifie si vous êtes censé ou non les qualifier d'espace de noms dans une instance.
Ihe Onwuka le
1
@Ihe, ce n'est pas correct: ou en tout cas, c'est susceptible de semer la confusion. Si une déclaration d'élément local n'a pas form = qualifié, alors la propriété {target namespace} du composant de schéma de déclaration d'élément est "absente", ce qui signifie que la propriété URI de l'espace de noms de l'instance d'élément doit également être "absente".
Michael Kay
@MichaelKay Pour moi, c'est encore plus déroutant. La question est de savoir si la page d'exemple se trouve dans l'espace de noms nul, car si c'est le cas, la spécification ne dit pas simplement que le paramètre elementFormDefault = unqualified place les éléments définis localement dans l'espace de noms nul. C'est dire que cette page ne devrait pas être qualifiée d'espace de noms dans une instance la même chose que dire que la page n'est pas dans un espace de noms cos si c'est pourquoi la spécification ne dit pas simplement cela et pourquoi un schéma avec un targetNamespace valide des choses qui ne le sont pas dans cet espace de noms?
Ihe Onwuka le
1
Il ne "dit simplement que" parce que vous le décrivez de manière très informelle: l'expression "mettre un élément dans l'espace de noms nul" n'utilise pas la terminologie de la spécification XSD; la spécification préfère utiliser une terminologie beaucoup plus soignée, ce qui la rend souvent difficile à lire mais finit par être beaucoup plus précise.
Michael Kay le
1
En ce qui me concerne, c'est une réponse correcte telle que rédigée.
Michael Kay le
60

Considérez le ComplexType suivant AuthorTypeutilisé par l' authorélément

<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"/>

Si elementFormDefault="unqualified"

alors l'instance XML suivante est valide

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

l'attribut de nom de l'auteur est autorisé sans spécifier l'espace de noms (non qualifié). Tous les éléments qui font partie de <xsd:complexType>sont considérés comme locaux à complexType.

si elementFormDefault="qualified"

alors l'instance doit avoir les éléments locaux qualifiés

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

veuillez consulter ce lien pour plus de détails

Girish
la source
55

Nouvelle réponse détaillée et explication à une ancienne question fréquemment posée ...

Réponse courte : Si vous n'ajoutez pas elementFormDefault="qualified"à xsd:schema, la unqualifiedvaleur par défaut signifie que les éléments déclarés localement ne sont pas dans l' espace de noms .

Il y a beaucoup de confusion sur ce que elementFormDefaultfait, mais cela peut être rapidement clarifié avec un court exemple ...

Version simplifiée de votre 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>

Points clés:

  • L' assignmentélément est défini localement.
  • Les éléments définis localement dans XSD ne sont par défaut dans aucun espace de noms.
    • En effet, la valeur par défaut de elementFormDefaultest unqualified.
    • C'est sans doute une erreur de conception des créateurs de XSD.
    • La pratique standard est de toujours utiliser elementFormDefault="qualified" ce qui se assignmenttrouve dans l'espace de noms cible comme on s'y attendrait.
  • C'est un formattribut rarement utilisé sur les xs:elementdéclarations pour lesquelles elementFormDefaultétablit des valeurs par défaut.

XML apparemment valide

Ce XML semble être valide selon le XSD ci-dessus:

<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>

Remarquer:

  • L'espace de noms par défaut sur les assignmentslieux assignmentset tous ses descendants dans l'espace de noms par défaut ( http://www.levijackson.net/web340/ns).

Erreur de validation déroutante

Bien qu'il semble valide, le code XML ci-dessus génère l'erreur de validation déroutante suivante:

[Erreur] try.xml: 4: 23: cvc-complex-type.2.4.a: Un contenu non valide a été trouvé en commençant par l'élément «affectation». L'un des "{affectation}" est attendu.

Remarques:

  • Vous ne seriez pas le premier développeur à maudire ce diagnostic qui semble dire que le contenu est invalide car il s'attendait à trouver un assignmentélément mais il a en fait trouvé un assignmentélément. ( WTF )
  • Ce que cela signifie vraiment: Le {et }autour assignmentsignifie que la validation n'attendait assignment aucun espace de noms ici. Malheureusement, quand il dit qu'il a trouvé un assignmentélément, il ne mentionne pas qu'il l'a trouvé dans un espace de noms par défaut qui ne diffère d'aucun espace de noms.

Solution

  • La grande majorité du temps: ajoutez elementFormDefault="qualified"à l' xsd:schemaélément du XSD. Cela signifie qu'un XML valide doit placer des éléments dans l'espace de noms cible lorsqu'il est déclaré localement dans le XSD; sinon, un XML valide doit placer les éléments déclarés localement dans aucun espace de noms.
  • Minuscule minorité du temps: changez le XML pour se conformer à l'exigence du XSD qui ne assignmentsoit dans aucun espace de noms. Ceci peut être réalisé, par exemple, en ajoutant xmlns=""à l' assignmentélément.

Crédits: Merci à Michael Kay pour ses commentaires utiles sur cette réponse.

kjhughes
la source
12

Il est important de noter avec elementFormDefault qu'il s'applique aux éléments définis localement , généralement des éléments nommés à l'intérieur d'un bloc complexType, par opposition aux éléments globaux définis au niveau supérieur du schéma. Avec elementFormDefault = "qualifié", vous pouvez adresser des éléments locaux dans le schéma à partir du document xml en utilisant l'espace de noms cible du schéma comme espace de noms par défaut du document.

En pratique, utilisez elementFormDefault = "qualifié" pour pouvoir déclarer des éléments dans des blocs imbriqués, sinon vous devrez déclarer tous les éléments au niveau supérieur et y faire référence dans le schéma des éléments imbriqués en utilisant l'attribut ref, ce qui entraînera un schéma beaucoup moins compact.

Ce bit du XML Schema Primer en parle: http://www.w3.org/TR/xmlschema-0/#NS

stephan f
la source
Légère clarification sur ce qui semble être la réponse la plus précise. Avec elementFormDefault = qualifié, vous devez qualifier les éléments locaux dans l'espace de noms. S'il est défini sur non qualifié, vous ne devez pas les qualifier d'espace de noms.
Ihe Onwuka le
6

elementFormDefault = "qualifié" est utilisé pour contrôler l'utilisation des espaces de noms dans les documents d'instance XML (fichier .xml), plutôt que les espaces de noms dans le document de schéma lui-même (fichier .xsd).

En spécifiant elementFormDefault = "qualifié", nous imposons la déclaration d'espace de noms à utiliser dans les documents validés avec ce schéma.

Il est courant de spécifier cette valeur pour déclarer que les éléments doivent être qualifiés plutôt que non qualifiés. Cependant, comme attributeFormDefault = "unqualified" est la valeur par défaut, il n'est pas nécessaire de la spécifier dans le document de schéma, si l'on ne veut pas qualifier les espaces de noms.

Feri
la source
elementFormDefault s'applique uniquement aux éléments définis localement. Les éléments globaux doivent malgré tout être qualifiés d'espacement de noms.
Ihe Onwuka le
0

J'ai remarqué que XMLSpy (au moins la version 2011) a besoin d'un targetNameSpace défini si elementFormDefault = "qualifié" est utilisé. Sinon, ne validera pas. Et ne générera pas non plus de fichiers XML avec des préfixes d'espace de noms

Neal
la source