Estaba interesado en encontrar (o, si fuera necesario, desarrollar) un equivalente XSLT para JSON.
Como no he encontrado ninguno, estaba considerando el posible lenguaje de consulta que se usaría para hacer coincidir las rutas JSON para aplicar plantillas (desde JavaScript) cuando había una coincidencia (probablemente solo verificaba una matriz de patrones coincidentes en orden y me detenía en el primera plantilla que coincide, aunque permite el equivalente de xsl: apply-templates para mantener las plantillas para niños).
Soy consciente de JSONPath, JSONQuery y RQL como lenguajes de consulta JSON (aunque no estaba completamente claro si RQL admitía rutas absolutas y relativas). Cualquier sugerencia sobre los factores a considerar y las ventajas relativas de cada uno hacia tal uso.
fuente
Respuestas:
XML: XSLT :: JSON: x . ¿Qué es x ?
La respuesta más fácil sería x = JavaScript. Aunque podría presentar un caso para esto, se siente insatisfactorio. A pesar de que XSLT está técnicamente completo , existe una mala correspondencia entre el estilo declarativo de XSLT y los estilos más imperativos o funcionales que se ven en JavaScript.
Existen algunos lenguajes de consulta JSON independientes, como JSONPath , JSONiq y RQL, que pueden representar el término medio de XML: XPath :: JSON: y (o posiblemente, XQuery en lugar de XPath). Y cada base de datos de documentos centrada en JSON tiene un lenguaje de consulta relacionado con JSON .
Pero la realidad es que, a pesar de que hay algunos contendientes para la posición XSLT completa, como SpahQL , no hay equivalentes JSON generalmente aceptados y ampliamente compatibles con XSLT.
¿Por qué?
Con todos los JSON del mundo, ¿por qué no hay un análogo (más directo) de XSLT? Porque muchos desarrolladores ven XSLT como un experimento fallido. Cualquier motor de búsqueda llevará a citas como "XSLT es un fracaso envuelto en dolor". Otros han argumentado que si estuviera mejor formateado, sería más popular. Pero el interés en XSLT generalmente ha disminuido con los años . Muchas herramientas que lo admiten solo admiten la versión 1.0 , que es una especificación de 1999. ¿Especificaciones de quince años? Hay una especificación 2.0 mucho más nueva, y si la gente estuviera entusiasmada con XSLT, sería compatible. No lo es
En general, los desarrolladores han optado por procesar y transformar documentos XML con código, no con plantillas de transformación. Por lo tanto, no es sorprendente que al trabajar con JSON, en general, elijan hacerlo en su idioma nativo, en lugar de agregar un sistema de transformación "extranjero" adicional.
fuente
Si bien Jonathan habla en gran medida sobre la naturaleza de XSLT como lenguaje en su respuesta, creo que hay otro ángulo a considerar.
El propósito de XSLT era transformar documentos XML en algún otro documento (XML, HTML, SGML, PDF, etc.). De esta manera, XSLT se usa con frecuencia, efectivamente, como un lenguaje de plantilla.
Existe una gran variedad de bibliotecas de plantillas, incluso si se restringe a las bibliotecas de JavaScript (lo cual no debería necesitar, ya que el JS en JSON solo se refiere a la génesis de la notación y no debe interpretarse que implica que JSON es solo para JavaScript). Este selector de motor de plantilla ofrece una indicación de la variedad de opciones de JS que existen.
La última mitad de sus preguntas habla más sobre los lenguajes de consulta y la versión XML de estos sería XPath (no XSLT). Como notó, hay una variedad de opciones allí y no tengo nada que agregar a esa lista. Esta área es relativamente nueva, por lo que te sugiero que elijas una y la sigas.
fuente
Aquí hay algunos ejemplos de lo que puede hacer con mi (pequeño [jslt.min.js] ) JSLT - Transformaciones ligeras de JavaScript:
https://jsfiddle.net/YSharpLanguage/c7usrpsL/10
( [jslt.min.js] pesa ~ 3.1kb minificado )
es decir, solo una función,
... que realmente imita el modelo de procesamiento de XSLT (1.0) .
(cf. las funciones internas "transformar" y "plantilla", en el cuerpo de Per)
Entonces, en esencia, simplemente se integra todo en ese único
function Per ( subject ) { ... }
que bifurca su evaluación sobre el tipo de su (también) argumento único, para implementar, ya sea:1) Asunto de la matriz
creación / filtrado / aplanamiento / agrupación / ordenación / conjunto de nodos, si el sujeto es una matriz, donde el conjunto de nodos resultante (también una matriz ) se amplía y se vincula a los métodos nombrados en consecuencia ( solo la instancia de matriz devuelta de la llamada
Per ( subjectArray )
es extendido; es decir, Array.prototype se deja intacto)es decir, Per :: Array
-->
Array(los métodos de extensión de la matriz resultante tienen nombres que se explican por sí mismos, como groupBy, orderBy, flattenBy, etc., véase el uso en los ejemplos)
2) Asunto de cuerda
interpolación de cadenas , si el sujeto es una cadena
("Por" luego devuelve un objeto con un método
map ( source )
, que está vinculado a la cadena de plantilla del asunto )es decir, Per :: String
-->
{map :: ( AnyValue-->
String )}p.ej,
rendimientos:
mientras cualquiera de
o
produce lo mismo:
pero sólo
rendimientos
3) Transformar sujeto
Transformación similar a XSLT , si el sujeto es un hash con un miembro "$" convencionalmente definido que proporciona la matriz de reglas de reescritura (e igual que en (2), "Per" luego devuelve un objeto con un método
map ( source )
vinculado al sujeto transformar - donde"ruleName" en
Per ( subjectTransform [ , ruleName ])
es opcional y proporciona una funcionalidad similar a <xsl: nombre de la llamada-template = "nombre_plantilla"> ...)es decir, Per :: ( Transform [, ruleName :: String ])
-->
{map :: ( AnyValue-->
AnyValue )}con
Transformar :: {$ :: Matriz de reescritura de reglas [rw.r.] }
( pares de funciones de predicado y plantilla [rw.r.] )
por ejemplo, dado (... otro ejemplo artificial)
luego
rendimientos:
mientras ... (muy parecido
<xsl:call-template name="betterGenderString">...
)rendimientos:
y
rendimientos:
4) De lo contrario
la función de identidad , en todos los demás casos
es decir, Per :: T
-->
T(es decir,
Per === function ( value ) { return value ; }
)Nota
en (3) arriba, un "this" de JavaScript en el cuerpo de una función de plantilla está vinculado al contenedor / propietario Transform y su conjunto de reglas (como se define en la matriz $: [...]) - por lo tanto, haciendo la expresión "Per (this)", en ese contexto, un equivalente funcionalmente cercano a XSLT
<xsl:apply-templates select="..."/>
«HTH
fuente
Recientemente creé una biblioteca, json-transforma , exactamente para este propósito:
https://github.com/ColinEberhardt/json-transforms
Utiliza una combinación de JSPath , un DSL modelado en XPath y un enfoque de coincidencia de patrones recursivo, inspirado directamente por XSLT.
Aquí hay un ejemplo rápido. Dado el siguiente objeto JSON:
Aquí hay una transformación:
Lo que produce lo siguiente:
Esta transformación se compone de tres reglas. El primero coincide con cualquier automóvil fabricado por Honda, que emite un objeto con una
Honda
propiedad y luego coincide de forma recursiva. La segunda regla coincide con cualquier objeto con unamaker
propiedad, generando las propiedadesmodel
yyear
. La final es la transformación de identidad que coincide recursivamente.fuente
No creo que alguna vez obtenga una variante JSON para JSON per se. Existen varios motores de plantillas, como Jinja2 de Python, Nunjucks de JavaScripts, Groovy MarkupTemplateEngine y muchos otros que deberían ser adecuados para lo que desea. .NET tiene soporte de serialización / deserialización T4 y JSON, por lo que también tiene eso.
Dado que los datos JSON desrserializados serían básicamente una estructura de diccionario o mapa, eso simplemente pasaría a su motor de plantillas y usted iteraría sobre los nodos deseados allí. La plantilla transforma los datos JSON.
fuente