Que font les convertisseurs de syntaxe
JSON, YAML, XML, TOML et CSV ne contiennent pas les mêmes choses. Cette page indique exactement comment chaque forme est mappée, quelles conversions entraînent des pertes et ce que l'outil refuse de faire.
Ce qu'il convertit
Neuf conversions dirigées : JSON vers YAML, YAML vers JSON, JSON vers XML, XML vers JSON, JSON vers TOML, TOML vers JSON, YAML vers TOML, TOML vers YAML et JSON vers CSV. Chacun s'exécute dans l'onglet de votre navigateur ; rien n'est téléchargé.
Chaque conversion fonctionne de la même manière en interne : le document source est lu dans une valeur JavaScript ordinaire et cette valeur est écrite dans le format cible. YAML to TOML n'est pas un cas particulier, c'est le lecteur YAML suivi du rédacteur TOML. C'est pourquoi les mises en garde ci-dessous sont indiquées par format plutôt que par paire : une mise en garde concernant les dates et heures TOML s'applique partout où TOML apparaît.
CSV est en écriture seule, et délibérément. Lire CSV signifie deviner un délimiteur, un dialecte de citation, si la première ligne est un en-tête et un type pour chaque cellule – quatre suppositions, chacune desquelles un convertisseur se trompe tranquillement. C'est un travail pour un outil qui demande.
XML : attributs, tableaux et règles que nous avons choisies
XML n'a pas de mappage JSON canonique, les conventions ont donc dû être choisies. Ils sont visibles à l'écran chaque fois que XML est l'un des deux formats, et ce sont ceux-là.
Les attributs deviennent des clés d'objet préfixées par @. <user id="7"><name>Ada</name></user> se lit comme {"user":{"@id":"7","name":"Ada"}}. Le préfixe est ce qui empêche un attribut et un élément enfant du même nom de se regrouper en une seule clé — <user id="7"><id>other</id></user> conserve les deux.
Le texte à l'intérieur d'un élément qui possède également des attributs ou des éléments enfants se trouve sous la clé #text. Un élément ne contenant rien d'autre que du texte se réduit à ce texte. Une section CDATA réside sous #cdata, son contenu est donc visiblement des données plutôt que du balisage.
Les éléments frères et sœurs répétés deviennent un tableau. Un nom d'élément qui apparaît une seule fois ne devient pas un tableau — XML ne donne à un analyseur aucun moyen de distinguer « une liste avec un élément » d'« une valeur unique », et aucun convertisseur ne peut inventer cette information. Si vous avez besoin d'une forme stable, c'est un argument en faveur d'un schéma, pas d'un convertisseur plus intelligent.
Les préfixes des espaces de noms sont conservés textuellement : <ns:item> est la clé ns:item et xmlns:ns est l'attribut @xmlns:ns. Rien n'est résolu, réécrit ou supprimé, car la résolution d'un préfixe supprime le texte que le document contenait réellement.
Une balise à fermeture automatique se lit comme une chaîne vide. La déclaration XML, les instructions de traitement et les commentaires sont supprimés. Dans l'autre sens, l'outil écrit sa propre déclaration et jamais un DOCTYPE.
En écrivant du XML, une clé qui n'est pas un nom d'élément XML légal — une avec un espace, une commençant par un chiffre, une commençant par les lettres xml — est refusée par son nom plutôt que réécrite en silence. Un élément discrètement renommé produit un document qui ne se valide par rien.
Les entités externes sont refusées, pas simplement désactivées
Un document XML peut déclarer des entités dans un DOCTYPE. Un analyseur qui les étend est la vulnérabilité XXE : une entité déclarée SYSTEM "file:///etc/passwd" lit un fichier local, une personne pointant sur une URL fait une requête contrôlée par un attaquant, et une chaîne d'entités internes est le "milliard de rires" déni de service qui transforme quelques centaines d'octets en gigaoctets.
Ce convertisseur ne configure pas un analyseur pour faire attention aux DOCTYPEs. Il refuse tout document en contenant un, avant que l'analyseur ne reçoive un seul octet, sans possibilité de désactiver le refus. Cela fait de la garantie une propriété de notre code plutôt que du paramètre par défaut d'une dépendance - et la différence compte, car les valeurs par défaut changent entre les versions et notre propre refus est couvert par des tests qui l'alimentent avec chaque charge utile XXE standard et affirment que rien n'a été récupéré et que rien n'a été développé.
Le coût pratique : un document avec un DOCTYPE ne sera pas converti ici même s'il est inoffensif. Supprimez le DOCTYPE si le contenu vous appartient.
Les dates et heures TOML n'ont d'équivalent nulle part ailleurs
TOML 1.0 a quatre types temporels et JSON, YAML et XML n'en ont aucun : décalage date-heure (1979-05-27T07:32:00Z), local date-heure (1979-05-27T07:32:00, sans zone, délibérément), date locale (1979-05-27) et heure locale (07:32:00).
Chacune devient la chaîne RFC 3339 exactement telle qu'elle a été écrite, et la conversion vous indique à quelles valeurs elle a fait cela et à laquelle des quatre sortes chacune appartenait. L’alternative – émettre un seul instant UTC pour les quatre – déplacerait une heure locale dans une zone que le document a explicitement refusé d’indiquer, ce qui est une mauvaise réponse plutôt qu’une réponse avec perte.
La reconversion produit des chaînes entre guillemets, pas des dates et des heures. Un aller-retour TOML vers JSON vers TOML modifie donc les types de ces valeurs. Il n'y a aucun moyen de contourner ce problème sans inventer une convention que l'outil de réception devrait partager, et en inventer une en silence serait pire.
TOML les entiers sont signés 64-bit ; Les nombres JSON sont des doubles IEEE-754. Un entier passé 2^53 - 1 devient une chaîne, avec le chemin nommé dans un avertissement, plutôt que de perdre ses derniers chiffres à cause d'un arrondi que vous ne remarqueriez pas.
TOML n'a pas de valeur nulle. Une clé nulle est omise de la sortie et nommée dans un avertissement ; une valeur nulle à l'intérieur d'un tableau devient une chaîne vide, car sa suppression entraînerait un décalage à chaque index ultérieur. La racine d'un document TOML est toujours une table, donc un tableau ou une simple valeur à la racine est refusé avec une phrase expliquant pourquoi.
YAML : ancres, flux et problème norvégien
YAML est lu avec un schéma restreint qui ne peut produire que des chaînes, des nombres, des booléens, des valeurs nulles, des listes et des cartes. Les balises qui construisent des objets arbitraires — !!js/function, !!python/object/apply, !!binary — sont refusées, c'est la raison pour laquelle la restriction existe : un chargeur qui les honore est un constructeur d'objets arbitraires portant les vêtements d'un fichier de configuration.
Les ancres et les alias sont résolus en données répétées. Un document qui dépasse un million de valeurs une fois ses alias suivis est refusé plutôt que autorisé à geler l'onglet ; un alias récursif est carrément refusé, car aucun autre format ici ne peut exprimer un cycle.
Un flux de plusieurs documents séparés par --- devient un tableau de documents, et la conversion l'indique. Aucun autre format de cet outil n'a de flux, donc un tableau est le seul mappage honnête.
YAML interdit une clé de mappage répétée et chaque analyseur en gère une différemment. Cet outil conserve la dernière valeur — la règle utilisée par JSON.parse — et vous indique que cela s'est produit, avec la position de la répétition. Supprimer silencieusement un document serait pire ; choisir silencieusement une valeur sans le dire serait encore pire.
Le problème de la Norvège : dans YAML 1.1, les scalaires non cités y, oui, on, non, off et le code de pays NO se résolvent tous en booléens, c'est ainsi qu'une liste de codes de pays se transforme en une liste de vrais et de faux. Cet outil lit YAML 1.2, où seuls vrai et faux sont des booléens, donc NO reste la chaîne NO. Lorsqu'il écrit YAML, il cite chaque chaîne qu'un analyseur 1.1 lirait mal — 'NON', 'oui', 'on', '1.0', '0755', '2001-12-14' — donc la sortie est peut être transmis en toute sécurité à un outil qui n'a pas été déplacé vers 1.2. Cela coûte quelques guillemets et achète l'exactitude.
Les chaînes qui ressemblent à des nombres conservent leurs guillemets pour la même raison : "0755" reste une chaîne plutôt que de devenir 755, et "1.0" reste une chaîne plutôt que de devenir 1.
Les commentaires se perdent dans tous les sens. JSON, CSV et les autres n'ont nulle part où les mettre, et il n'y a aucun moyen de deviner où ils devraient aller en revenant.
JSON vers CSV : l'aplatissement et l'apostrophe qui arrête une formule
Un tableau devient les lignes, un enregistrement par élément. Un objet dont la propriété unique contient un tableau utilise ce tableau comme lignes, car {"users": [ ... ]} est majoritairement une table avec une étiquette - et la conversion indique à haute voix qu'elle l'a fait. Tout autre objet est une seule ligne. Une chaîne nue, un nombre ou un nul est refusé : un rectangle a besoin d'enregistrements.
Les objets et tableaux imbriqués sont aplatis en noms de colonnes en pointillés, avec un point pour les clés d'objet et les indices de tableau : adresse.ville, tags.0, tags.1. Un séparateur, une règle. Une clé qui contient déjà un point rend le nom de sa colonne ambigu avec un chemin imbriqué ; l'outil avertit plutôt que d'inventer un schéma d'évasion qu'aucune feuille de calcul ne comprendrait.
Les clés sont regroupées sur chaque ligne, dans le premier ordre d'apparition. Une ligne sans champ obtient une cellule vide plutôt qu'une colonne décalée, et la conversion avertit que les lignes étaient irrégulières. Un objet ou un tableau vide devient une cellule vide sous son propre chemin plutôt que de disparaître.
La citation suit la RFC 4180 : un champ contenant le délimiteur, un guillemet double, CR ou LF est entouré de guillemets doubles et un guillemet intégré est écrit deux fois. Les enregistrements sont séparés par CRLF. Les champs avec des espaces de début ou de fin sont également cités, car les feuilles de calcul les suppriment silencieusement autrement. Unicode passe inchangé et une marque d'ordre d'octet peut être préfixée pour les feuilles de calcul qui en ont besoin pour lire UTF-8.
La formule injectable est celle qui mord. Une cellule commençant par =, +, -, @, une tabulation ou un retour chariot est exécutée sous forme de formule par Excel, LibreOffice Calc et Google Sheets au moment de l'ouverture du fichier. =cmd|'/c calc'!A1 est la démonstration que tout le monde cite ; =IMPORTXML(...) est celui qui envoie discrètement la feuille quelque part. Un convertisseur qui écrit une telle chaîne textuellement a transformé vos données en exécution de code par quelqu'un d'autre, dans un fichier qui semble inerte.
Ainsi, une cellule de texte commençant par l'un de ces caractères est préfixée par une apostrophe, que toutes les principales feuilles de calcul lisent comme " ceci est du texte " et ne s'affiche pas dans la cellule. Les nombres sont laissés seuls : un -5 numérique est un nombre, pas une formule. Le nombre de cellules échappées est signalé et l'évasion peut être désactivée — auquel cas l'outil indique clairement ce que vous venez de désactiver.
CSV ne peut pas distinguer une chaîne vide d'une valeur nulle. Les deux deviennent une cellule vide et la conversion compte les valeurs nulles pour que vous sachiez que cela s'est produit.
Limites et que se passe-t-il lorsque vous en atteignez une
Chaque format a une limite de caractères, appliquée avant même le téléchargement d'un analyseur : 8 millions pour JSON, 4 millions pour XML et pour une source CSV, 2 millions pour YAML et TOML. Au-delà de cela, l'outil refuse le numéro exact, plutôt que de devenir un onglet qui ne répond plus et perd ce que vous avez collé. La sortie
CSV est en outre limitée à 100,000 lignes et 2,000 colonnes, car un tableau profondément imbriqué s'aplatit en une colonne par élément et quelques mégaoctets de JSON peuvent devenir une table qu'aucune feuille de calcul ne pourra ouvrir.
Les entrées vides et contenant uniquement des espaces sont signalées comme vides plutôt que converties en un document nul ou vide. Une syntaxe invalide est signalée avec une ligne et une colonne dans les quatre formats lisibles.
Les analyseurs eux-mêmes sont téléchargés uniquement lorsqu'une conversion en a besoin. L'ouverture de la boîte à outils pour décoder un JWT ne récupère aucun d'entre eux.
Qu'arrive-t-il à ce que vous collez
- Chaque conversion, hachage, décodage et différence s'exécute dans l'onglet de votre navigateur. Aucune entrée n'est téléchargée, enregistrée ou stockée sur un serveur, car aucun serveur n'est impliqué une fois la page chargée.
- Les hachages proviennent de la propre implémentation Web Crypto du navigateur et les UUID de son générateur aléatoire cryptographiquement sécurisé. Ni l’un ni l’autre n’implique un appel réseau.
- Rien de ce que vous tapez n’est écrit dans le stockage local ou dans un cookie. Le rechargement de la page la supprime ; la fermeture de l'onglet le supprime.
- Les analyses à l'échelle du site s'exécutent uniquement sur l'hôte de production canonique configuré et sont divulguées dans la politique de confidentialité ; les hôtes locaux et de prévisualisation le refusent. Les valeurs collées, les jetons, les URL et le contenu des fichiers sont exclus des propres événements d'analyse de ToolAcre. La publicité est désactivée dans la configuration actuelle.
- Cela dit : un JWT ou une clé API est un identifiant en direct. La bonne habitude est de ne jamais en coller un dans une page Web que vous n’avez pas écrite, aussi dignes de confiance que ses affirmations – y compris celle-ci.
Questions
Pourquoi mon document XML échoue-t-il avec « déclare un DOCTYPE » ?
Parce qu'il contient une déclaration de type de document, et ce convertisseur refuse chacune d'entre elles plutôt que de faire confiance à un paramètre d'analyseur pour gérer les entités en toute sécurité. Supprimez le DOCTYPE si le contenu vous appartient. Il n’y a aucune option pour l’autoriser.
Pourquoi ma date/heure TOML est-elle revenue sous forme de chaîne entre guillemets ?
Parce que JSON, YAML et XML n'ont pas de type de date. La date et l'heure ont été converties en texte RFC 3339 sous lequel il a été écrit, qui est une chaîne dans tous les autres formats. La reconversion produit donc une chaîne, et l'outil vous avertit au moment où cela se produit plutôt que de vous le permettre plus tard.
Pourquoi une de mes cellules CSV commence-t-elle par une apostrophe ?
Parce que son texte commence par =, +, -, @, une tabulation ou un retour chariot, et qu'une feuille de calcul exécute une telle cellule comme formule à l'ouverture du fichier. L'apostrophe marque la cellule comme texte ; cela ne fait pas partie de la valeur une fois la cellule lue. Vous pouvez désactiver l'échappement et l'outil vous dira ce que cela signifie.
Pourquoi un seul élément XML répété n’est-il pas un tableau ?
Parce que XML ne fournit aucun moyen de distinguer une liste d'une valeur unique. Les deux sont écrits de la même manière. Faire une supposition dans un sens ou dans l’autre serait une erreur la moitié du temps, c’est pourquoi l’outil rapporte ce qui se trouve réellement là.
Puis-je reconvertir le CSV en JSON ici ?
Non. Pour lire correctement un fichier CSV, il faut choisir un délimiteur, un dialecte de citation, si la première ligne est un en-tête et un type pour chaque cellule. Un convertisseur qui devine les quatre se trompe discrètement, ce qui est la pire façon de se tromper. Utilisez un outil CSV qui demande.
Pourquoi "NO" n'est-il pas converti en false ?
Parce que ce comportement appartient à YAML 1.1 et cet outil lit YAML 1.2, où seuls vrai et faux sont des booléens. Le comportement 1.1 est la raison pour laquelle le code pays de la Norvège est une plaisanterie courante dans la gestion de la configuration. Lorsque l'outil écrit YAML, il cite ces chaînes afin qu'aucun analyseur 1.1 en aval ne puisse non plus les lire mal.
Limites
- CSV est écrit, jamais lu. Il n'y a pas de conversion CSV en JSON ici, par choix.
- Les commentaires se perdent dans toutes les directions, dans tous les formats qui en contiennent.
- Une date/heure TOML devient une chaîne dans tous les autres formats, donc un aller-retour TOML modifie ces types. Il n’existe pas de chemin sans perte.
- Un document XML contenant un DOCTYPE est refusé catégoriquement, y compris les anodins, et le refus ne peut pas être désactivé.
- Un seul élément XML répété ne peut pas être distingué d'un élément non répété, donc XML vers JSON vers XML ne renvoie pas toujours la forme d'origine.
- Le contenu mixte XML (texte entrelacé avec des éléments enfants) perd la position du texte par rapport aux enfants et ne peut pas faire d'aller-retour.
- Les valeurs XML sont des chaînes à moins que l'inférence de type ne soit activée, car XML ne déclare aucun type ; avec inférence activée, "0755" et "NO" sont sujets aux erreurs de lecture habituelles.
- TOML n'a pas de valeur nulle : les clés nulles sont supprimées de la sortie TOML et les valeurs nulles à l'intérieur des tableaux deviennent des chaînes vides.
- La racine d'un document TOML doit être une table, donc un tableau ou un scalaire JSON ne peut pas du tout être converti en TOML.
- JSON sont des doubles IEEE-754. Les entiers après 2^53 sont convertis en chaînes plutôt qu'arrondis silencieusement, ce qui change leur type.
- CSV ne peut pas distinguer une chaîne vide d'une chaîne nulle ; les deux sont écrits sous forme de cellule vide.
- L'aplatissement CSV utilise un point pour les clés d'objet et les indices de tableau, de sorte qu'une clé qui contient déjà un point produit un nom de colonne ambigu qui est averti mais pas échappé.
- Les ancres et alias YAML sont résolus plutôt que conservés ; la sortie n'a pas d'ancres et un alias récursif est refusé car aucun format cible ne peut exprimer un cycle.
- Les entrées sont plafonnées par format : 8 millions de caractères pour JSON, 4 millions pour XML, 2 millions pour YAML et TOML – et les documents surdimensionnés sont refusés plutôt que traités lentement.
- Rien ici ne se valide par rapport à un schéma. Un document peut être converti proprement tout en étant erroné par rapport à son objectif.