JSON does not care about order in objects (key-value pairs) but it does in arrays, so maybe you should use JSON array where the order matters.
Anyway, you can do that kind of JSON/XML transformation with standard XSLT 3.0 which introduced functions for JSON-to-XML and XML-to-JSON conversion. In Java, the SAXON XSLT library supports them (in all editions including the free one) since v9.7.
Here is an excerpt from a XSLT stylesheet applying transformation from JSON input (link to full XSLT ):
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.w3.org/2005/xpath-functions" expand-text="yes"
xmlns:my-prefix="urn:the:namespace:of:my:xsd">
<!-- Reference example for JSON to XML transformation: https://www.saxonica.com/papers/xmlprague-2016mhk.pdf -->
<!-- expand-text option allows to use text value templates in XSLT 3.0 -->
<xsl:output encoding="UTF-8" indent="yes" method="xml" />
<xsl:template name="xsl:initial-template">
<xsl:apply-templates select="json-to-xml(.)" />
</xsl:template>
<!-- This is just an example of applying a template when matching some key from JSON. -->
<xsl:template match="map[@key='key_of_something_to_change']">
<!-- Fill in whith whatever transformation you want to apply in this case. Plenty of examples to change order of XML elements, such as:
https://stackoverflow.com/questions/37442799/xslt-change-element-order
-->
...
</xsl:template>
...
</xsl:stylesheet>
Then some sample code to use that XSLT from Java, assuming that SAXON XSLT >= 9.7 is on your classpath (this example takes input JSON as a String and outputs the result to System.out just for testing but you can adapt to handle other kinds of input/output with SAXON API easily):
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.XdmAtomicValue;
import net.sf.saxon.s9api.Xslt30Transformer;
import net.sf.saxon.s9api.XsltExecutable;
import net.sf.saxon.trace.XSLTTraceListener;
...
private static final XsltExecutable JSON_TO_XML_XSLT_EXEC;
static
{
try
{
final Processor xsltProc = new Processor(false);
JSON_TO_XML_XSLT_EXEC = xsltProc.newXsltCompiler().compile(new StreamSource(new File("/path/to/my/xslt/stylesheet/file"));
}
catch (final SaxonApiException e)
{
throw new RuntimeException("Cannot create XSLT processor for my stylesheet", e);
}
}
private static void convertJsonToXml(final String inputJson, final Path outXmlFile)
{
final Xslt30Transformer xslt = JSON_TO_XML_XSLT_EXEC.load30();
/*
* Line below is useful for debugging, esp. to see what the output from the json-to-xml function looks like before further processing. Else remove it.
*/
xslt.setTraceListener(new XSLTTraceListener());
try
{
xslt.setGlobalContextItem(new XdmAtomicValue(inputJson));
/*
* Call default template "xsl:initial-template"
*/
xslt.callTemplate(null, xslt.newSerializer(System.out));
}
catch (final SaxonApiException e)
{
throw new RuntimeException("Failed to apply XSLT", e);
}
}