node.jsjsonxsltsaxon-js

Is it possible to use Saxon-JS to convert a JSON file to a different JSON file without transiting through XML?


I'm doing research to solve a transformation problem that is fundamentally based entirely in JSON, and while imperative code-based solutions are possible, there is appeal in using an established technology like XSLT and leveraging its many features rather than trying to in-house everything from scratch. I'm fairly inexperienced with XSLT but I would love for this effort to provide a reason to learn it.

I've read that JSON is included in XSLT 3.0 and XPath 3.1 specs, and that Saxon-JS supports these, and furthermore that Saxon-JS has a node.js version. This has me very interested, but I haven't found much in the way of tutorials that provide instruction about how to transform JSON into other JSON; instead the focus appears to be on transforming JSON into XML.

This question is kind of broad and so I'd be happy to know just whether this is possible, and maybe where to look to start learning, but stackoverflow likes examples. With that in mind, what would a stylesheet look like that converts the first of these JSON documents to the second?

Source:

{
    "contents" : [
        {
            "id": 1,
            "color": "blue",
            "hexcode": "#0000FF"
        },
        {
            "id": 2,
            "color": "green",
            "hexcode": "#00FF00"
        },
        {
            "id": 3,
            "color": "red",
            "hexcode": "#FF0000"
        }
    ]
}

Output:

[
    {
        "id": "contents1",
        "color": {
            "name": "blue",
            "hexcode": "#0000FF"
        }
    },
    {
        "id": "contents2",
        "color": {
            "name": "green",
            "hexcode": "#00FF00"
        }
    },
    {
        "id": "contents3",
        "color": {
            "name": "red",
            "hexcode": "#FF0000"
        }
    }
]

Solution

  • Yes, it's possible, as Martin shows. However, XSLT still has a little way to go before JSON-to-JSON transforms work as smoothly as XML-to-XML. The main limitations in my experience are:

    (a) it isn't as easy to write match patterns for xsl:template that match "nodes" in a JSON tree

    (b) because there's no parent or ancestor axis for JSON, the processing of a particular "node" in the JSON tree has no access to the context in which it appears, which means it's necessary to pass that context down using template parameters (tunnel parameters come in very handy for this.)

    In your example, the input data is completely flat, so these problems don't show up.