Jolt – JSON to JSON transformation
bazaarvoice.github.io
bazaarvoice.github.io
I guess that depends on one's definition of transformation but:
echo '{"hello": "world"}' | jq '{brave:{"new": .hello}}'
it also doesn't even require JSON input, meaning one could use it strictly for composing valid output JSON: # where -n = null input
jq -n --arg foo bar '{"meet me": ("at the "+$foo)}'
I use it for transforming AWS responses all the time. I put jq up there with vim as one of the "must have" tools. In fact, the keys `%!jq .` are burned into my fingers because I type them a lot_ed: fixed a mobile character replacement, added in the --arg flag I couldn't remember at the time_
Also, my project https://requesthub.xyz/ relies entirely on the transformation capabilities of jq. See real world examples of jq transformations in this context: https://gist.github.com/fiatjaf/1d57953aa285b9bf5b51712268cf...
The result was a sort of system whereby data going into a function would be automatically 'reshaped'. It worked well as a proof-of-concept, but obviously was too fragile for most uses (though it's used in the automatic graphs in Kajero[3]). The difference here seems to be that the spec defines the actual transformations, rather than just the desired final structure.
[1] https://github.com/joelotter/reshaper [2] https://github.com/joelotter/smolder [3] https://github.com/joelotter/kajero
Actually, having done some work on XSLT these days again I was joking to a colleague at work that one day someone will surely think what a great idea it would be to create a programming language in JSON to transform JSON to other JSON. And lo and behold, a few days later I stumble over this.
I have to admit, XSLT looks far nicer to me, but that might be familiarity and a proper specification to read to understand things instead of just a bunch of examples.
It would probably be more useful if it more explicitly tied itself to the Java implementation (i.e. stop pretending to be its own thing) or were more abstract to be worth implementing in other languages.
In the latter case it'd be helpful if the operations were part of the actual unified DSL instead of having a DSL for each transformation (with the implication that each transformation is applied individually?).
EDIT: But if you abstract this away from Java, why not just use JSON Patch: https://tools.ietf.org/html/rfc6902
It's like I'm the only one using electric lighting while all the hipsters are upgrading their wax-dipped hemp brands to artisan whale oil …
JSON format+JSON.parse() make you loose the graph structure of the data you have on your server and that you send to the client. Because it is basically a tree structure.
The Semantic Web defines a graph description langage called N3. If your server can serialize and send the data in such a format, and if you use the function N3.parse() on your client, you eventually retrieve, on the client, a graph of in-memory objects that corresponds to the data graph on your server. You can then traverse that graph in any direction you want.
So basically, with N3, you never lose the graph structure of your data.
And you do not need to restructure your JSON.
https://www.w3.org/TeamSubmission/turtle/
Turtle is a subset of N3. N3 has some syntactic sugar plus also some syntax to describe first-order logic statements that include implication and the use of existential and universal qualifiers.
Tim-Berners Lee started work on this software:
which implements reasoning on N3, but it is not particularly performant for a number of reasons -- one is that it does not implement any description logic optimizations, another is that it is written in Python, another is that it doesn't have a particularly sophisticated rules engine.
The closest thing to a standard in this area is ISO Common Logic
https://en.wikipedia.org/wiki/Common_Logic
which is based on KIF but uses RDF for the basic data structures, i.e. you can load RDF data and work on it with Common Logic.
There are plenty of people who use logical reasoning over RDF data but usually they use something specific to their tools, such as the Jena Rules Engine, or some kind of Prolog -- it also is not that hard to stuff RDF data into a SAT solver, theorem prover or similar tools.
It's a conspicuous absense that there is no common standard for production rules.
Oh, and btw, the package is here: https://www.npmjs.com/package/n3
I completely agree that trying to represent a graph structure of data properly into JSON can be inordinately difficult.
What has happened is that people have tried a lot of things and some have succeeded and some have failed. For instance, OWL seems to have become an inpediment to progress rather than a useful tool. On the other hand, people are starting to understand what JSON-LD is and they like it.
See https://developers.google.com/schemas/formats/json-ld
Also note that by simply specifying a namespace to put the terms in you can transform JSON into usable RDF and even put multiple documents in and see them as a comprehensive graph.
is based on similar principles, but more concrete.
Store the graph in rocksdb, transform using the iterator library (only 2-3 transforms currently there, more coming) and then send the "json" over the wire without copy. We're looking at flatbuffers.
Unfortunately, it's not public yet — though we have working libraries in JavaScript and Go (a heavily modified fork of Kubernetes' JSONPath code) we intend to release — mostly because we want to publish a proper spec. In fact, we're looking for a good name for it, as we feel that releasing "JSONPath 2.0" would be a little presumptious. I was thinking something like JSONMatch. If there's sufficient interest I could prioritize it (email me!).
Our own version of JSONPath is intended for both searching and patching documents in general. A simple search would be something like:
friends[name == 'bob'].id
or shoppingItems[1:3][description, id]
We use this to declaratively extract data from documents, but also change it. The patching support lets you do things like: match(document, "..[role == 'owner'].role")
.set('admin');
This will set "role". It gets rather magical and beautiful when you have multiple paths that involve unions, subindexed arrays and constraints.We also have a separate patch notation, expressed in JSON, to declaratively transform documents. It uses these JSONPaths to select and set values. We might write a spec for that, too, although I'm not sure the utility outside our app is that great.
Edit: Just to be clear some of the most terrifying code I've ever seen (and possibly wrote) was in XSLT.
// yes I understand the use cases of functional code
Microsoft's non-standard implementation of XSLT [2] is "out of the tarpit" Turing complete [3] because it lets you write handlers in JavaScript and other languages, to actually get some useful work done and call external librarys, without bending over backwards.
Of course Microsoft's non-standard extensions to XSLT aren't supported outside of Windows. But after using it, going back to plain XSLT was pretty frustrating to me, and in many cases it was easier just to forget about XSLT and write straight-up JavaScript code with XML parsing and XPath expressions.
There's nothing that XSLT can do that you can't easily implement in a JavaScript library. At this point it's better to start with JavaScript and forget about XSLT, instead trying to use XSLT, hitting a wall, realizing you want to ship on some platform other than Windows, then rewriting it all in Java, then realizing you want it to run in the browser, then rewriting it all in JavaScript, which you should have started with in the first place.
Another point for JavaScript: In the past decade, a whole hell of a lot more effort has been put into making JavaScript run fast, than making XSLT run fast.
[1] https://en.wikipedia.org/wiki/Document_Style_Semantics_and_S...
Even XPath 3 is Turing complete
You would never want to write a JPEG decoder in XSLT, but the fact that it might be possible if you were willing to bend over backwards, write unmaintainable code that runs incredibly slowly and requires colossal amounts of memory, misses the point.
For getting real work done in the real world, where big companies have mountains of data to process, and are required to pay real money for electrical power and computing equipment, Microsoft decided to add the ability to call JavaScript, Visual Basic, and other scripts from XSLT templates.
Because it's just too hard to get anything of interest done in XSLT, and it's trivial and convenient in JavaScript, and there's probably already a library to do it.
I thought the point of XSLT wasn't really arbitrary processing but to transform XML into other formats (mostly, but not always, other forms of XML such as XSL-FO) - and it was reasonably good at that.
DSSSL was extensible in Scheme, so all transforms had access to arbitrary processing, by the standard.
XSLT was not extensible in any language, so Microsoft went ahead and made a non-standard extension that integrated JavaScript, Visual Basic, C#, and all other IScriptingEngine/.NET compatible languages, much in the same way standard HTML web browsers like Internet Explorer integrate scripting languages.
"The languages that you can use differ between the MSXML and .NET implementations. In MSXML (from version 2.0 on), you can use either VBScript or JavaScript. In .NET, however, you can use any .NET-supported language including C#, Visual Basic, JScript.NET, and even JScript, as before. The ability to use strongly typed languages like C# and Visual Basic .NET makes this an even more attractive opportunity." https://msdn.microsoft.com/en-us/library/bb986124.aspx
Lots of people got lots of work done with Microsoft's non-standard scriptable XSLT, because they believed it was just too hard to get anything of interest done in standard non-scriptable XSLT, but worth paying the price of being locked into Microsoft's ecosystem.
I think it's better to forget about XSLT entirely, because it's a long lost cause, weak and ineffective at what it was designed, and use JavaScript and libraries like XPath to transform XML (and that goes squared for JSON), to reap the advantages of the latest JavaScript engines and libraries.
If Jolt is meant to be a language-independent standard, there should be a definitive reference implementation in JavaScript.
(in reply to arethuza's reply:)
Yes, I'd rather have all the great things you can do in domain specific languages like XSLT (like XPath, CSS, RegEx, etc) packaged up into nice libraries I can call from JavaScript, instead of being big complex hybrid frameworks that call my little snippets of JavaScript, like Microsoft's extended XSLT.
Here is an raytracer written in XQuery: https://dev.w3.org/cvsweb/2011/QT3-test-suite/app/Demos/rayt... (imported modules are in the directory above) looks quite maintainable to me.
XQuery is pretty much XPath-with-functions, and XPath 3 has anonymous functions, so you can directly translate it to XPath 3 by replacing `declare function foo(..` with `let $foo := function(...`
Once it is XPath, you can put everything in a xsl:value-of tag.
The mountain tops are modern JavaScript engines. How much work have Mozilla, Google, Apple, IBM and many other big organizations and excellent engineers poured into making XSLT run fast and efficiently in the last decade, compared to how much has been applied to JavaScript? Can you cite any interesting SIGPLAN articles about XSLT optimization? Have any commercial games shipped using a ray tracer implemented in XSLT?
http://www.ibm.com/support/knowledgecenter/SS9H2Y_7.5.0/com....
Shouldn't
<json:string name="ficoScore"> > 640</json:string>
be <json:string name="ficoScore"> > 640</json:string>Edit: Forgot to say thanks for pointing that out!
> For characters such as > where XML defines a built-in entity but does not require its use in all circumstances, it is implementation-dependent whether the character is escaped.
(https://www.w3.org/TR/xslt-xquery-serialization-31/#serphase...)
It can do transformations, where you write the output structure, and then pick the values from the input JSON. E.g. to transform from {"a": [{"b": 123}, {"b": 456}]} to {"c": [123,456]}, you could write an XPath expression {"c": a/b }
But in general, JSON, XML, S-expressions, yaml, HTML, and many data interchange programs are all 95% the same hierarchical data structure.
I wanted to make a cross-dataformat XPath subset that would work on all of them, and even allow a format that mixed the formats as needed in a MIME-esque document format, but the parser... oh god the parser.
This guy's project was like the initial steps of mine: use whatever XML tools exist, but that kills streaming processing and doesn't pass cursory smell tests...
I like this though, it is food for thought.
S-expressions can also represent graphs. I have a vague recollection that YAML can as well.
An S-expression example:
(nodes #1=(a #2=(b #1# #3=(c #2# #3#)) #3#) #2# #3#)That's actually how I checked that I had the syntax right: I wrote:
(let ((*print-circle* t) (*print-case* :downcase)
(print '(nodes #1=(a #2=(b #1# #3=(c #2# #3#)) #3#) #2# #3#))
nil)
Thus proving that reading & printing work well.Seriously, Lisp is an awesome language.
http://blog.notdot.net/2006/9/Serializing-JavaScript-objects...
http://philogb.github.io/blog/2009/03/24/sharp-variables/
https://developer.mozilla.org/en-US/docs/Archive/Web/Sharp_v...
It's like complaining about regular expressions "Are we _really_ going to reinvent all the spectacularly bad ideas of Perl, except this time in Python?
I think it's human nature, as often as I see it repeating throughout history (and not just in the tech industry). Just wait, there will be a new JSON just over the horizon which will close the circle and bring back a very simplistic serialization format with a minimal number of built-in structures.
Perhaps it would be better to create a C++ of serialization formats, all the features out of the gate, so you can pick and choose from the beginning. Again, I think human nature means we can't go back to XML (too much horror associated with SOAP and WSDL), or even continue with JSON (custom and subtly incompatible parsers being built around the core to handle missing features).
Old solutions accumulate cruft and start to need more expertise (and sometimes, straight wisdom) to operate well. People complain, blog posts are written, inertia and inaction are challenged; babies are thrown out of the bathwater as clean-room rewrites commence with different stacks, different tradeoffs, and often, different bikeshedding.
The new, shiny tool is promoted on its merits; some of that excitement inspires hype, which takes on a life of its own. Through a combination of informed usage and less-informed codemashing, the tool accumulates users from all walks of life, who turn into willing or unwilling stakeholders in its future. Development pressures pull the product in different ways, some people leave, eventually only the really passionate or really locked-in remain. These people acquire domain knowledge, "sometimes straight wisdom", making the solution -- its merits, design rationale, tradeoffs, and lessons learned -- more opaque to newcomers. Those newcomers find that existing solutions don't appear to do what they need at the level of complexity that they can grok. The cycle repeats.
It's already here: protobufs.
We all cried about the abuse of XML and its inherent foibles, but I seriously doubt that replacing that with JSON and Markdown was the best choice.
This type of thing is targeted towards enterprise and the usual large and well-established environments.
Environments where replacing a 20+ year old app written in COBOL isn't a question.
No one is ever going to say "Let's write this new app in Groovy!". On top of management saying "WTF is Groovy?", it'll never get approved because it's a huge amount of technical risk to take on.
In big enterprise, you want to have your stuff written in the most supportable language you can find resources for. This is why Java is so popular - it's a lot easier to find a Java developer than it is someone who knows Groovy, Rust, Scala, etc.
By mentioning Apache Groovy in the same breath as Cobol, Java, Rust, and Scala, you're comparing apples and oranges. Groovy is to the JVM what bash is to Linux. Groovy is a dynamically-typed language, best used for writing scripts used for glue code, testing, build control, and what not, whereas those others are statically compiled, used for creating actual systems. Although static compilation was added later, virtually no-one uses it.
http://www.wrox.com/WileyCDA/WroxTitle/XSLT-2-0-and-XPath-2-...