I have to take the input as JSON and transform it to another JSON by using XSLT.
Input JSON:
{
"members": [
{
"name": "Molecule Man1",
"age": 29,
"secretIdentity": "Dan Jukes"
},
{
"name": "Molecule Man2",
"age": 30,
"secretIdentity": "Martin"
}
]
}
I want to convert the above JSON to look like this:
{
"resourceType": "Test",
"type": {
"name": "Member"
},
"displayName": "Molecule Man",
"attributes": {
"test": [
{
"value": "29"
}
],
"testing": [
{
"value": "Dan Jukes"
}
]
}
}
I have tried with the below code and am not able to get the desired output JSON. I am getting an error SERE0023 JSON serialization: cannot handle a sequence of length 2 and also getting the error as saxon:array is not recognized as Saxon instruction.Saxon extensions require Saxon-PE or higher, while trying to implement <saxon::array> .
I have used Saxon HE(12.0) dependency.
Java Code
package com.practice;
import net.sf.saxon.s9api.*;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
public class JsonToXsltToJson {
public static void main(String[] args) throws FileNotFoundException, SaxonApiException {
Processor processor = new Processor(false);
TransformJson(processor);
}
static void TransformJson(Processor processor) throws
FileNotFoundException, SaxonApiException {
JsonBuilder jsonBuilder = processor.newJsonBuilder();
XdmValue input = jsonBuilder.parseJson(new InputStreamReader(new FileInputStream("input.json"), StandardCharsets.UTF_8));
XsltCompiler xsltCompiler = processor.newXsltCompiler();
XsltExecutable xsltExecutable = xsltCompiler.compile(new StreamSource(new File("jsonTransform.xsl")));
Xslt30Transformer xslt30Transformer = xsltExecutable.load30();
xslt30Transformer.applyTemplates(input, xslt30Transformer.newSerializer(System.out));
}
}
sample.xsl
:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all">
<xsl:param name="nodes" as="map(*)*"/>
<xsl:template name="init">
<xsl:apply-templates select="($nodes)"/>
</xsl:template>
<xsl:template match=".">
<xsl:map>
<xsl:map-entry key="'resourceType'" select="'Test'"/>
<xsl:map-entry key="'type'">
<xsl:map-entry key="'name'" select="'Member'"/>
</xsl:map-entry>
<xsl:map-entry key="'displayName'" select= "?members?1?name"/>
<xsl:map-entry key="'attributes'">
<xsl:map-entry key="'age'">
<xsl:map-entry key="'value'" select="?members?1?age"/>
</xsl:map-entry>
<xsl:map-entry key="'secretIdentity'">
<xsl:map-entry key="'value'" select="?members?1?secretIdentity"/>
</xsl:map-entry>
</xsl:map-entry>
</xsl:map>
</xsl:template>
<xsl:output method="json" indent="yes"/>
</xsl:stylesheet>
```
2
Answers
I think you want a nested map:
And for
you might
You could also do this all in XPath: