web-dev-qa-db-fra.com

Pourquoi JSON n'est-il pas valide si un entier commence par un zéro non significatif?

J'importe des fichiers JSON dans mon projet Parse.com et je reçois toujours l'erreur "clé non valide: paire de valeurs".

Il indique qu'il y a un "8" inattendu.

Voici un exemple de mon JSON:

}
 "Manufacturer":"Manufacturer",
 "Model":"THIS IS A STRING",
 "Description":"",
 "ItemNumber":"Number12345",
 "UPC":083456789012,
 "Cost":"$0.00",
 "DealerPrice":" $0.00 ",
 "MSRP":" $0.00 ",
}

Si je mets à jour le JSON en supprimant le 0 de "UPC":083456789012, ou le convertir en "UPC":"083456789012", il devient valide.

JSON ne peut-il vraiment pas accepter un entier commençant par 0, ou existe-t-il un moyen de contourner le problème?

36
DJSrA

Un 0 en tête indique un nombre octal en JavaScript. Un nombre octal ne peut pas contenir de 8; par conséquent, ce numéro n'est pas valide. De plus, JSON ne prend pas (officiellement) en charge les nombres octaux, donc formellement le JSON n'est pas valide, même si le nombre ne contiendrait pas de 8. Certains analyseurs le supportent cependant, ce qui peut entraîner une certaine confusion. D'autres analyseurs le reconnaîtront comme une séquence invalide et lanceront une erreur, bien que l'explication exacte qu'ils donnent puisse différer.

Solution: Si vous avez un numéro, ne le stockez jamais avec des zéros non significatifs. Si vous avez une valeur qui doit avoir un zéro non significatif, ne la traitez pas comme un nombre, mais comme une chaîne. Stockez-le avec des guillemets autour.

Dans ce cas, vous avez un UPC qui doit être composé de 12 chiffres et peut contenir des zéros non significatifs. Je pense que la meilleure façon de le stocker est chaîne.

C'est discutable, cependant. Si vous le traitez comme un code-barres, en voyant le 0 de tête comme partie intégrante de celui-ci, alors la chaîne a du sens. D'autres types de codes-barres peuvent même contenir des caractères alphabétiques.

D'autre part. A UPC est un nombre, et le fait qu'il soit rempli à gauche avec des zéros à 12 chiffres pourrait être considéré comme une propriété d'affichage. En fait, si vous l'avez laissé à 13 chiffres en ajoutant un 0 supplémentaire, vous avez un code EAN, car EAN est un surensemble de UPC.

Si vous avez un montant monétaire, vous pouvez l'afficher sous la forme € 7.30, pendant que vous le stockez en tant que 7.3, il peut donc également être judicieux de stocker un code produit sous forme de nombre.

Mais cette décision vous appartient. Je ne peux que vous conseiller d'utiliser une chaîne, ce qui est ma préférence personnelle pour ces codes, et si vous choisissez un nombre, vous devrez alors supprimer le 0 pour le faire fonctionner.

53
GolezTrol

L'une des parties les plus déroutantes de JavaScript est que si un nombre commence par un 0 qui n'est pas immédiatement suivi d'un ., il représente un octal, pas une décimale.

JSON emprunte à la syntaxe JavaScript mais évite les fonctionnalités déroutantes, donc interdit simplement les nombres avec des zéros en tête (à moins qu'ils ne soient suivis d'un .) purement et simplement.

Même si ce n'était pas le cas, il n'y aurait aucune raison de s'attendre à ce que le 0 pour être toujours dans le nombre lors de son analyse depuis 02 et 2 ne sont que des représentations de différence du même nombre (si vous forcez la décimale).

Si le zéro non significatif est important pour vos données, vous avez probablement une chaîne et non un nombre.

"UPC":"083456789012"

Un code produit est un identifiant, pas quelque chose avec lequel vous faites des calculs. Ce devrait être une chaîne.

8
Quentin

Le UPC doit être au format chaîne. Pour l'avenir, vous pouvez également obtenir un autre type de UPC tel que GS128 ou des codes d'identification de produit basés sur une chaîne. Définissez votre base de données) colonne en chaîne.

1
causita

Formellement, c'est parce que JSON utilise DecimalIntegerLiteral dans sa production JSONNumber:

JSONNumber ::
    -_opt DecimalIntegerLiteral JSONFraction_opt ExponentPart_opt

Et DecimalIntegerLiteral ne peut commencer que par 0 Si c'est 0:

DecimalIntegerLiteral ::
    0
    NonZeroDigit DecimalDigits_opt

La justification derrière est probablement:

  • Dans la grammaire JSON - pour réutiliser les constructions de la grammaire ECMAScript principale.
  • Dans la grammaire ECMAScript principale - pour faciliter la distinction entre DecimalIntegerLiteral de HexIntegerLiteral et OctalIntegerLiteral. OctalIntegerLiteral en premier lieu.

Voir ces productions:

 HexIntegerLiteral ::
     0x HexDigit
     0X HexDigit
    HexIntegerLiteral HexDigit

...

OctalIntegerLiteral ::
    0 OctalDigit
    OctalIntegerLiteral OctalDigit
1
lexicore

Si un entier commence par 0 en JavaScript, il est considéré comme la valeur octale (base 8) de l'entier au lieu de la valeur décimale (base 10). Par exemple:

var a = 065; //Octal Value
var b = 53;  //Decimal Value
a == b; //true
0
tantalum

Je pense que la façon la plus simple d'envoyer votre numéro par JSON est d'envoyer votre numéro sous forme de chaîne.

0
Alireza MH