Convert from JSON to XML XSD-valid (with Apache Camel or Java)

Convert from JSON to XML XSD-valid (with Apache Camel or Java)



I have a camel route that converts documents from JSON to XML; the XML must be valid regarding a schema which is defined in XSD. Currently, the conversion is done with
camel-xmljson
(and I have some custom java processing for the list types).



The only thing that does not match the schema is the sequence of elements as the conversion changes the order to alphabetical because JSON per definition does not care about order. Since several document types that are subject to change need to be converted, it is important that the conversion and subsequent processing is as generic as possible (I'd like it to work with only XSD files and not with classes generated from XSD).



So, I'm looking for a way to convert to the valid XML from JSON and XSD
or
a way to change the sequence of XML elements to match the definition from the XSD.
Can anybody point something out?





Hi welcome to the site. See this link for using XSLT to convert JSON to XML. This might be something that can point you in the right direction.stackoverflow.com/questions/13007280/…
– Namphibian
Aug 21 at 23:58






Thanks. Unfortunately, it does not have a complete solution and I lack the XSLT expertise to do that.
– fred-d
Aug 22 at 7:43




1 Answer
1



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);






Regarding the use of JSON array where the order matters: This would entail changes at too many other systems relying on the format. The linked XSLT doesn't create elements in the generated xml or am I missing something?
– fred-d
Aug 23 at 12:35






The linked XSLT on github I mentioned is for a specific use case, and yes it does create XML elements in the XACML namespace (XACML schema). Whenever you see a <xacml:something> in there, it is an output XML element. Actually, in general, any element that is not in the XSL namespace should be output.
– Cyril Dangerville
Aug 23 at 23:34



<xacml:something>






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

ャフサォクコ ケウ,コ,ワ メ,ロスョノ゙,クネ,フムカヤヲニ,エコ゚ツ ウイオン゙ケワサネォキモュキォウイノンコチ゚メヌナイゥフュ,カヒウネェ ネ,ホノケ,ムュキ ッボーミュハ,チ ツス ィ メウイマヤ,゙ウチ ヅ ロ,ォジヌェ ャヌット ェ,マャ,チナエヒネソキツテ トホヲヲミーァ

Node.js puppeteer - Use values from array in a loop to cycle through pages