Created on 04-25-2016 08:33 PM
Easily convert any XML document to JSON format using TransformXML processor. Save following stylesheet in a file. Use TransformXML processor and specify xslt stylesheet. It will convert any XML document to JSON format.
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="/">{ <xsl:apply-templates select="*"/>} </xsl:template> <!-- Object or Element Property--> <xsl:template match="*"> "<xsl:value-of select="name()"/>" : <xsl:call-template name="Properties"/> </xsl:template> <!-- Array Element --> <xsl:template match="*" mode="ArrayElement"> <xsl:call-template name="Properties"/> </xsl:template> <!-- Object Properties --> <xsl:template name="Properties"> <xsl:variable name="childName" select="name(*[1])"/> <xsl:choose> <xsl:when test="not(*|@*)">"<xsl:value-of select="."/>"</xsl:when> <xsl:when test="count(*[name()=$childName]) > 1">{ "<xsl:value-of select="$childName"/>" :[<xsl:apply-templates select="*" mode="ArrayElement"/>] }</xsl:when> <xsl:otherwise>{ <xsl:apply-templates select="@*"/> <xsl:apply-templates select="*"/> }</xsl:otherwise> </xsl:choose> <xsl:if test="following-sibling::*">,</xsl:if> </xsl:template> <!-- Attribute Property --> <xsl:template match="@*">"<xsl:value-of select="name()"/>" : "<xsl:value-of select="."/>", </xsl:template> </xsl:stylesheet>
That's it !
Created on 05-05-2016 04:13 PM
The above XSL, has a small bug. For example if you take the following XML:
<MyElement myAttribute="100" />
It will produce the following JSON:
{ "MyElement" : { "myAttribute" : "100", } }
In essence if there is a single attribute there should not be a comma. Below is an updated version of the above that fixes the above.
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="/">{ <xsl:apply-templates select="*"/>} </xsl:template> <!-- Object or Element Property--> <xsl:template match="*"> "<xsl:value-of select="name()"/>" : <xsl:call-template name="Properties"/> </xsl:template> <!-- Array Element --> <xsl:template match="*" mode="ArrayElement"> <xsl:call-template name="Properties"/> </xsl:template> <!-- Object Properties --> <xsl:template name="Properties"> <xsl:variable name="childName" select="name(*[1])"/> <xsl:choose> <xsl:when test="not(*|@*)">"<xsl:value-of select="."/>" </xsl:when> <xsl:when test="count(*[name()=$childName]) > 1">{ "<xsl:value-of select="$childName"/>" :[ <xsl:apply-templates select="*" mode="ArrayElement"/>] } </xsl:when> <xsl:otherwise>{ <xsl:apply-templates select="@*"/> <!-- Handle case where parent has a sibling and there are attributes, thus we need a comma after the last attribute --> <xsl:if test="count(descendant::*) > 0">,</xsl:if> <xsl:apply-templates select="*"/> } </xsl:otherwise> </xsl:choose> <xsl:if test="following-sibling::*">,</xsl:if> </xsl:template> <!-- Attribute Property --> <xsl:template match="@*">"<xsl:value-of select="name()"/>" : "<xsl:value-of select="."/>" <!-- Only add the comma if the current attribute is not the last one for this element --> <xsl:if test="position() != last()">,</xsl:if> </xsl:template> </xsl:stylesheet>
Created on 09-20-2016 10:09 AM
Hi,
on generating arrays I found that this does only work if the first child of an object is a repeating one (see input below).
If I remove the K01 segment the K14s will go into an Array.
Do you have any hints?
Hans
Input:
<?xml version="1.0" encoding="ISO-8859-1"?> <ORDERS05> <IDOC BEGIN="1"> <E1EDK01 SEGMENT="1"> <ACTION>000</ACTION> <CURCY>EUR</CURCY> <WKURS>1.00000</WKURS> <ZTERM>V1A3</ZTERM> <BELNR>0011592846</BELNR> <VSART>01</VSART> <VSART_BEZ>Standard per LKW</VSART_BEZ> <RECIPNT_NO>A132125</RECIPNT_NO> </E1EDK01> <E1EDK14 SEGMENT="1"> <QUALF>006</QUALF> <ORGID>01</ORGID> </E1EDK14> <E1EDK14 SEGMENT="1"> <QUALF>007</QUALF> <ORGID>01</ORGID> </E1EDK14> <E1EDK14 SEGMENT="1"> <QUALF>008</QUALF> <ORGID>I001</ORGID> </E1EDK14> <E1EDK14 SEGMENT="1"> <QUALF>012</QUALF> <ORGID>ZDEK</ORGID> </E1EDK14> <E1EDK14 SEGMENT="1"> <QUALF>010</QUALF> <ORGID>060</ORGID> </E1EDK14> <E1EDK14 SEGMENT="1"> <QUALF>016</QUALF> <ORGID>0043</ORGID> </E1EDK14> </IDOC> </ORDERS05>
Created on 11-15-2016 12:41 AM
Please use the XSLT code located here - it is more complete than the XSLT code provided
Created on 03-28-2017 11:10 AM
There is problem with both XSLT schema.
Below example is not converted correct.
<?xml version="1.0" encoding="UTF-8"?> <note> <country> <city>Stockholm</city> </country> <country> <code>FR</code> <city>Paris</city> <streets> <road>Paris</road> </streets> </country> <country> <code>DK</code> <city>Copenhagen</city> <streets> <road>Paris</road> <no>1</no> </streets> </country> </note>
Created on 05-22-2017 06:42 PM
I applied this stylesheet, and it does convert xml to json. But problem is the json format is not 100% correct, for example the ':' is becoming ',', and the last child always having ',' there cause problem.
Can we please get the stylesheet corrected?
Thanks.
Created on 05-31-2017 10:20 AM
@James Dong @Hans Pointner This stylesheet is incomplete for arbitrary XML conversion, I suggest you try https://github.com/bramstein/xsltjson I've documented use of it with the TransformXML processor in a new article here: https://community.hortonworks.com/content/kbentry/105547/nifi-xml-to-json-shredding-a-generalised-so...
Created on 09-21-2017 08:23 AM
Loved the article and I would use this tool to validate the result. https://jsonformatter.org/xml-formatter
Created on 10-10-2017 08:48 PM
@Shishir Saxena I think this formatter puts a comma after every json element, before '}' too. For example '..., "key": "value", }'. These an invalid json is created.
This is working as I experienced: https://github.com/bramstein/xsltjson/blob/master/conf/xml-to-json.xsl
Created on 02-14-2019 05:16 AM
can you please upload the sample xml and nifi template here
Thanks
Nitin