Je souhaitais trouver (ou si nécessaire développer) un équivalent XSLT pour JSON.
Comme je n'en ai pas trouvé, je considérais le langage de requête possible à utiliser pour faire correspondre les chemins JSON afin d'appliquer des modèles (à partir de JavaScript) quand il y avait une correspondance (probablement juste vérifier un tableau de modèles correspondants dans l'ordre, et s'arrêter à la premier modèle qui correspond, tout en permettant l'équivalent de xsl: apply-templates pour garder les modèles en cours pour les enfants).
Je connais JSONPath, JSONQuery et RQL en tant que langages de requête JSON (même si je ne savais pas très bien si RQL supportait les chemins absolus et relatifs). Toutes suggestions sur les facteurs à considérer et les avantages relatifs de chacun vers une telle utilisation.
la source
Réponses:
XML: XSLT :: JSON: x . Qu'est-ce que x ?
La réponse la plus simple serait x = JavaScript. Bien que vous puissiez justifier cela, cela ne vous semble pas satisfaisant. Même si XSLT est techniquement complet , il existe une faible correspondance entre le style déclaratif de XSLT et les styles plus impératifs ou fonctionnels vus en JavaScript.
Il existe quelques langages de requête JSON autonomes, comme JSONPath , JSONiq et RQL, qui pourraient remplacer le milieu de XML: XPath :: JSON: y (ou peut-être XQuery plutôt que XPath). Et chaque base de données de documents axée sur JSON possède un langage de requête lié à JSON .
Mais la réalité est que, bien qu'il y ait quelques prétendants au poste XSLT complet, comme SpahQL , il n'y a pas d'équivalent JSON généralement accepté et largement pris en charge par XSLT.
Pourquoi?
Avec tout le JSON dans le monde, pourquoi n'y a- t - il pas un analogue (plus direct) du XSLT? Parce que de nombreux développeurs considèrent XSLT comme une expérience ayant échoué. Tout moteur de recherche mènera à des citations comme «XSLT est un échec enveloppé de douleur». D'autres ont fait valoir que s'il était simplement mieux formaté, il serait plus populaire. Mais l' intérêt pour XSLT a généralement diminué au fil des ans . De nombreux outils qui le prennent en charge ne prennent en charge que la version 1.0 , qui est une spécification de 1999. Spécifications de quinze ans? Il existe une spécification 2.0 beaucoup plus récente, et si les gens étaient enthousiastes à propos de XSLT, elle serait prise en charge. Ça ne l'est pas.
En gros, les développeurs ont choisi de traiter et de transformer les documents XML avec du code, pas des modèles de transformation. Il n'est donc pas surprenant qu'en travaillant avec JSON, ils choisissent généralement de le faire dans leur langue maternelle, plutôt que d'ajouter un système de transformation "étranger" supplémentaire.
la source
Alors que Jonathan parle largement de la nature du XSLT en tant que langage dans sa réponse, je pense qu'il y a un autre angle à considérer.
Le but de XSLT était de transformer des documents XML en un autre document (XML, HTML, SGML, PDF, etc.). De cette façon, XSLT est fréquemment utilisé, efficacement, comme langage de modèle.
Il existe un large éventail de bibliothèques de modèles, même si vous vous limitez aux bibliothèques JavaScript (dont vous ne devriez pas avoir besoin, car le JS dans JSON ne fait référence qu'à la genèse de la notation et ne doit pas être interprété comme impliquant JSON est uniquement pour JavaScript). Ce sélecteur de moteur de modèle donne et indique la variété des options JS disponibles.
La seconde moitié de vos questions parle davantage des langages de requête et la version XML de ceux-ci serait XPath (pas XSLT). Comme vous l'avez noté, il existe une variété d'options et je n'ai rien à ajouter à cette liste. Ce domaine est relativement nouveau, je vous suggère donc d'en choisir un et d'y aller.
la source
Voici quelques exemples de ce que vous pouvez faire avec mon (petit [jslt.min.js] ) JSLT - Transformations légères JavaScript:
https://jsfiddle.net/YSharpLanguage/c7usrpsL/10
( [jslt.min.js] pèse ~ 3,1 ko minifié )
c'est-à-dire une seule fonction,
... qui imite en fait le modèle de traitement de XSLT (1.0) .
(cf. les fonctions internes "transform" et "template", dans le corps de Per)
Donc, en substance, c'est tout simplement tout cuit dans ce single
function Per ( subject ) { ... }
qui forge son évaluation sur le type de son argument (également) unique, à implémenter, soit:1) Sujet du tableau
création / filtrage de l'ensemble de nœuds / aplatissement / regroupement / classement / etc , si l'objet est un tableau, où l'ensemble de nœuds résultant (un tableau également) est étendu avec et lié aux méthodes nommées en conséquence ( seule l' instance de tableau renvoyée de l'appel à
Per ( subjectArray )
est étendu; c.-à-d., Array.prototype n'est pas modifié)c'est-à-dire Per :: Array
-->
Array(les méthodes d'extension du tableau résultant ayant des noms explicites tels que, groupBy, orderBy, flattenBy, etc. - cf. l'utilisation dans les exemples)
2) Sujet de chaîne
interpolation de chaîne , si le sujet est une chaîne
("Per" renvoie ensuite un objet avec une méthode
map ( source )
, qui est liée à la chaîne de modèle objet )c'est-à-dire, Per :: String
-->
{map :: ( AnyValue-->
String )}par exemple,
rendements:
tandis que
ou
donne le même:
mais, seulement
les rendements
3) Transformer le sujet
Transformation similaire à XSLT , si le sujet est un hachage avec un membre "$" défini de manière conventionnelle fournissant le tableau de règles de réécriture (et comme dans (2), "Per" renvoie ensuite un objet avec une méthode
map ( source )
liée au sujet transformer - où"ruleName" dans
Per ( subjectTransform [ , ruleName ])
est facultatif et fournit des fonctionnalités similaires à <xsl: call-template name = "templateName"> ...)c'est-à-dire Per :: ( Transform [, ruleName :: String ])
-->
{map :: ( AnyValue-->
AnyValue )}avec
Transform :: {$ :: Tableau de règles de réécriture [rw.r.] }
( [rw.r.] paires de fonctions prédicat et modèle)
par exemple, étant donné (... un autre exemple artificiel)
ensuite
rendements:
tandis que ... (très semblable
<xsl:call-template name="betterGenderString">...
)rendements:
et
rendements:
4) Sinon
la fonction d'identité , dans tous les autres cas
c'est-à-dire Per :: T
-->
T(c.-à-d.
Per === function ( value ) { return value ; }
)Remarque
dans (3) ci-dessus, le "this" d'un JavaScript dans le corps d'une fonction de modèle est donc lié à la transformation conteneur / propriétaire et à son ensemble de règles (tel que défini par le tableau $: [...]) - donc, faisant de l'expression "Per (this)", dans ce contexte, un équivalent fonctionnellement proche des XSLT
<xsl:apply-templates select="..."/>
«HTH,
la source
J'ai récemment créé une bibliothèque, json-transforms , exactement à cet effet:
https://github.com/ColinEberhardt/json-transforms
Il utilise une combinaison de JSPath , une DSL sur le modèle de XPath et une approche de correspondance de modèle récursive, directement inspirée de XSLT.
Voici un petit exemple. Étant donné l'objet JSON suivant:
Voici une transformation:
Qui a produit les éléments suivants:
Cette transformation est composée de trois règles. La première correspond à toute automobile fabriquée par Honda, émettant un objet avec une
Honda
propriété, puis correspondant récursivement. La deuxième règle fait correspondre tout objet avec unemaker
propriété, produisant les propriétésmodel
etyear
. La finale est la transformation d'identité qui correspond récursivement.la source
Je ne pense pas que vous obtiendrez jamais une variante JSON pour JSON en soi. Il existe plusieurs moteurs de modèles tels que Jinja2 de Python, Nunjucks JavaScripts, Groovy MarkupTemplateEngine et bien d'autres qui devraient être bien adaptés à ce que vous voulez. .NET prend en charge la sérialisation / désérialisation T4 et JSON, vous l'avez donc également.
Étant donné que les données JSON dersérialisées seraient essentiellement un dictionnaire ou une structure de carte, cela passerait simplement à votre moteur de modélisation et vous itéreriez sur les nœuds souhaités. Les données JSON sont ensuite transformées par le modèle.
la source