Quelle est la manière correcte de représenter des éléments XML nuls?

166

J'ai vu des nulléléments représentés de plusieurs manières:

L'élément est présent avec xsi:nil="true":

 <book>
     <title>Beowulf</title>
     <author xsi:nil="true"/>
 </book>

L'élément est présent, mais représenté comme un élément vide (ce qui, à mon avis, est faux car `` vide '' et nullsont sémantiquement différents):

 <book>
     <title>Beowulf</title>
     <author/>
 </book>

 <!-- or: -->
 <book>
     <title>Beowulf</title>
     <author></author>
 </book>

L'élément n'est pas du tout présent dans le balisage renvoyé :

 <book>
     <title>Beowulf</title>
 </book>

L'élément a un <null/>élément enfant (de TStamper ci-dessous):

 <book>
     <title>Beowulf</title>
     <author><null/></author>
 </book>

Existe-t-il une manière correcte ou canonique de représenter une telle nullvaleur? Existe-t-il des moyens supplémentaires que les exemples ci-dessus?

Le XML pour les exemples ci-dessus est artificiel, alors ne lisez pas trop loin. :)

Rob Hruska
la source

Réponses:

121

xsi: nil est la manière correcte de représenter une valeur telle que: Lorsque l'appel du DOM Niveau 2 getElementValue () est émis, la valeur NULL est renvoyée. xsi: nil est également utilisé pour indiquer un élément valide sans contenu même si ce type de contenu d'éléments n'autorise normalement pas les éléments vides.

Si une balise vide est utilisée, getElementValue () renvoie la chaîne vide ("") Si la balise est omise, alors aucune balise d'auteur n'est même présente. Cela peut être sémantiquement différent de le définir sur 'nil' (par exemple, définir "Series" sur nil peut signifier que le livre n'appartient à aucune série, tandis que l'omission de séries pourrait signifier que la série est un élément inapplicable à l'élément actuel.)

De: Le W3C

XML Schema: Structures introduit un mécanisme pour signaler qu'un élément doit être accepté comme · valide · lorsqu'il n'a pas de contenu malgré un type de contenu qui n'exige pas ou même n'autorise pas nécessairement un contenu vide. Un élément peut être · valide · sans contenu s'il a l'attribut xsi: nil avec la valeur true. Un élément ainsi étiqueté doit être vide, mais peut porter des attributs si le type complexe correspondant le permet.

Une clarification:
Si vous avez un élément book xml et que l'un des éléments enfants est book: series, vous avez plusieurs options pour le remplir:

  1. Suppression complète de l'élément - Cela peut être fait lorsque vous souhaitez indiquer que la série ne s'applique pas à ce livre ou que ce livre ne fait pas partie d'une série. Dans ce cas, les transformations xsl (ou d'autres processeurs basés sur des événements) dont le modèle correspond à book: series ne seront jamais appelées. Par exemple, si votre xsl transforme l'élément livre en ligne de tableau (xhtml: tr), vous pouvez obtenir le nombre incorrect de cellules de tableau (xhtml: td) en utilisant cette méthode.
  2. Laisser l'élément vide - Cela peut indiquer que la série est "", ou est inconnue, ou que le livre ne fait pas partie d'une série. Toute transformation xsl (ou tout autre analyseur basé sur Evernt) qui correspond à book: series sera appelée. La valeur de current () sera "". Vous obtiendrez le même nombre de balises xhtml: td en utilisant cette méthode que la méthode décrite ci-dessous.
  3. Utilisation de xsi: nil = "true" - Cela signifie que l'élément book: series est NULL, pas seulement vide. Votre transformation xsl (ou tout autre analyseur basé sur des événements) qui a un modèle correspondant book: series sera appelée. La valeur de current () sera vide (pas de chaîne vide). La principale différence entre cette méthode et (2) est que le type de schéma de book: series n'a pas besoin d'autoriser la chaîne vide ("") comme valeur valide. Cela n'a aucun sens pour un élément de série, mais pour un élément de langage défini comme un type énuméré dans le schéma, xsi: nil = "true" permet à l'élément de ne pas avoir de données. Un autre exemple serait les éléments de type décimal. Si vous voulez qu'ils soient vides, vous pouvez unir une chaîne énumérée qui n'autorise que "" et une décimale, ou utiliser une décimale qui ne peut être définie.
KitsuneYMG
la source
11
L'utilisation de xsi: nil est correcte, mais vous devez vous assurer qu'il se trouve dans l'espace de noms approprié: xmlns: xsi = " w3.org/2001/XMLSchema-instance "
STW
C'est en fait xmlns:xsi="http://w3.org/2001/XMLSchema-instance". Notez le http: // manquant. C'est important car la chaîne de l'espace de noms n'est en fait qu'une chaîne de l'analyseur xml et non un uri.
Burak Arslan le
9
Hé, je crois que c'est encore un peu faux. Ça devrait être xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance". Notez "www.". Voir w3.org/TR/xmlschema-1/#no-xsi
Janne Mattila
Comme indiqué dans ma réponse, je ne suis pas d'accord avec l'interprétation car ce n'est pas une représentation de l'état de l'élément, mais une contrainte sur l'utilisation de l'élément
Oakcool
2
@ChrisV: Non vrai, le xsi:préfixe doit être déclaré. Un analyseur XML prenant en charge les espaces de noms rejettera votre document XML si vous essayez d'utiliser le xsi:préfixe sans le déclarer. La spécification pertinente ici est w3.org/TR/xml-names/#nsc-NSDeclared ("Contrainte d'espace de noms: Préfixe déclaré") qui dit que les seuls préfixes prédéfinis sont xml:et xmlns:. Le schéma XML s'appuie sur la spécification des espaces de noms XML mais n'y ajoute aucun préfixe prédéfini supplémentaire, car cela violerait en fait la spécification des espaces de noms XML.
Simon Kissane
9

Il n'y a pas de réponse canonique, puisque XML n'a fondamentalement pas de concept nul. Mais je suppose que vous voulez un mappage Xml / objet (puisque les graphiques d'objets ont des valeurs nulles); la réponse pour vous est donc "tout ce que votre outil utilise". Si vous écrivez la manipulation, cela signifie ce que vous préférez. Pour les outils qui utilisent XML Schema, xsi:nilc'est la voie à suivre. Pour la plupart des mappeurs, omettre l'élément / l'attribut correspondant est le moyen de le faire.

StaxMan
la source
8

Cela dépend de la manière dont vous validez votre XML. Si vous utilisez la validation de schéma XML, la manière correcte de représenter les nullvaleurs est d' utiliser lexsi:nil attribut.

[ Source ]

Tormod Fjeldskår
la source
7

La documentation dans le lien w3

http://www.w3.org/TR/REC-xml/#sec-starttags

dit que ce sont les formulaires recommandés.

<test></test>
<test/>

L'attribut mentionné dans l'autre réponse est un mécanisme de validation et non une représentation d'état. Veuillez vous référer au http://www.w3.org/TR/xmlschema-1/#xsi_nil

XML Schema: Structures introduit un mécanisme pour signaler qu'un élément doit être accepté comme · valide · lorsqu'il n'a pas de contenu malgré un type de contenu qui ne nécessite pas ou même n'autorise pas nécessairement un contenu vide. Un élément peut être · valide · sans contenu s'il a l'attribut xsi: nil avec la valeur true. Un élément ainsi étiqueté doit être vide , mais peut porter des attributs si le type complexe correspondant le permet.

Pour clarifier cette réponse: Contenu

  <Book>
    <!--Invalid construct since the element attribute xsi:nil="true" signal that the element must be empty-->
    <BuildAttributes HardCover="true" Glued="true" xsi:nil="true">
      <anotherAttribute name="Color">Blue</anotherAttribute>
    </BuildAttributes>
    <Index></Index>
    <pages>
      <page pageNumber="1">Content</page>            
    </pages>
    <!--Missing ISBN number could be confusing and misguiding since its not present-->
  </Book>
</Books>
Oakcool
la source
7
C'est la recommandation pour les éléments vides ; êtes-vous d'avis que vide === null? Je crois qu'il y a une différence entre les deux, même si c'est souvent situationnel. Si vous déclarez qu'ils sont identiques, je vous recommande de mentionner cet argument dans votre réponse.
Rob Hruska
1
Vide n'est pas la même chose que null; si c'était le cas, cette question de stackoverflow n'aurait jamais été posée. Cette réponse est fausse. Cependant, le programmeur doit déterminer si la logique qui lira le xml est prête à gérer un élément manquant ou xsi: nil; sinon, il peut être nécessaire d'utiliser l'un de ces formulaires; autrement dit, il peut être nécessaire de perdre la distinction entre un élément nul / manquant et un élément vide.
ToolmakerSteve
@RobHruska oui, vous avez raison, c'est la définition d'un élément vide, mais si vous prenez en compte la définition du W3C pointée par KitsuneYMG, cela définit que l'élément doit être nul et je crois que cette représentation est plus de la définition du tag puis la représentation de son état actuel, donc je ne suis pas d'accord avec cette réponse, et je crois que le vide est la meilleure représentation d'un élément nul. L'idée est simple, pour maintenir une bonne structure, il faut que tous les éléments soient représentés sinon vous ne sauriez pas son existence, et donc pourriez le dénaturer.
Oakcool
4

Vous utilisez xsi:nillorsque la sémantique de votre schéma indique qu'un élément a une valeur par défaut et que la valeur par défaut doit être utilisée si l'élément n'est pas présent. Je dois supposer qu'il y a des gens intelligents pour qui la phrase précédente n'est pas une idée évidemment terrible, mais cela me semble neuf sortes de mauvais. Chaque format XML avec lequel j'ai travaillé représente des valeurs nulles en omettant l'élément. (Ou attribut, et bonne chance pour marquer un attribut avec xsi:nil.)

Robert Rossney
la source
Si, dans une application de publication de documents, vous souhaitez que la date sur la page de titre soit par défaut à la date actuelle si l'élément n'a pas de contenu, omettre datecomplètement l' élément n'est pas d'une grande aide, car l'application n'aura aucune idée de l'endroit où vous voulez sur la page de titre la date d'apparition. (Si l'élément omis n'a qu'un seul emplacement possible, ce n'est pas un problème; dans les vocabulaires de documents réels, presque tous les éléments ont de nombreux emplacements possibles.)
CM Sperberg-McQueen
4

Le simple fait d'omettre l'attribut ou l'élément fonctionne bien dans les données moins formelles.

Si vous avez besoin d'informations plus sophistiquées, les schémas GML ajoutent l'attribut nilReason, par exemple: dans GeoSciML :

  • xsi:nil avec une valeur de "vrai" est utilisé pour indiquer qu'aucune valeur n'est disponible
  • nilReasonpeut être utilisé pour enregistrer des informations supplémentaires sur les valeurs manquantes; cela peut être l'une des raisons GML standard ( missing, inapplicable, withheld, unknown), ou du texte précédé de other:, ou peut être un lien URI vers une explication plus détaillée.

Lorsque vous échangez des données, le rôle pour lequel XML est couramment utilisé, les données envoyées à un destinataire ou dans un but donné peuvent avoir un contenu masqué qui serait disponible pour quelqu'un d'autre qui a payé ou qui avait une authentification différente. Connaître la raison pour laquelle le contenu manquait peut être très important.

Les scientifiques s'inquiètent également des raisons pour lesquelles les informations manquent. Par exemple, s'il a été supprimé pour des raisons de qualité, ils peuvent souhaiter voir les données incorrectes d'origine.

Andy Dent
la source
2

Dans de nombreux cas, le but d'une valeur Null est de servir une valeur de données qui n'était pas présente dans une version précédente de votre application.

Disons que vous avez un fichier xml de votre application "ReportMaster" version 1.

Désormais, dans ReportMaster version 2, quelques attributs supplémentaires ont été ajoutés qui peuvent ou non être définis.

Si vous utilisez la représentation «aucune balise signifie null», vous obtenez une rétrocompatibilité automatique pour la lecture de votre fichier xml ReportMaster 1.

Jeroen Dirks
la source