I am trying to transform a Json input to XML in XSLT, however when doing the transformation I only get the children without any of their parent nodes, i.e. "Client", "ClientApp", "Payment" and "Bill" nodes they don't show up in the XML output, any idea what I'm missing in the template for these nodes to show up?
template
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xj="http://camel.apache.org/component/xj"
exclude-result-prefixes="xj">
<xsl:output omit-xml-declaration="no" encoding="UTF-8" method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="//object"/>
</xsl:template>
<xsl:template match="object[@xj:type != 'object' and @xj:type != 'array' and string-length(@xj:name) > 0]">
<xsl:variable name="name" select="@xj:name"/>
<xsl:element name="{$name}">
<xsl:value-of select="text()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*|node()"/>
</xsl:stylesheet>
Json
{
"Client": {
"Date": "2022-12-29T09:55:05",
"Lang": "es-CO",
"ClientApp": {
"Org": "COMPANY",
"Name": "NAME COMPANY",
"Version": 1
}
},
"Payment": {
"PaymentId": "00000000-0000-0000-0000-943534532",
"Bill": {
"PaymentId": "00000000-0000-0000-0000-943534532",
"PaymeentNumber": 63703,
"BillId": "00000000-0000-0000-0000-003223439138"
}
}
}
Output XML
<?xml version="1.0" encoding="UTF-8"?>
<Date>2022-12-29T09:55:05</Date>
<Lang>es-CO</Lang>
<Org>COMPANY</Org>
<Name>NAME COMPANY</Name>
<Version>1</Version>
<PaymentId>00000000-0000-0000-0000-943534532</PaymentId>
<PaymentId>00000000-0000-0000-0000-943534532</PaymentId>
<PaymeentNumber>63703</PaymeentNumber>
<BillId>00000000-0000-0000-0000-003223439138</BillId>
XML Input
<?xml version="1.0" encoding="UTF-8"?>
<object
xmlns:xj="http://camel.apache.org/component/xj" xj:type="object">
<object xj:name="Client" xj:type="object">
<object xj:name="Date" xj:type="string">2022-12-29T09:55:05</object>
<object xj:name="Lang" xj:type="string">es-CO</object>
<object xj:name="ClientApp" xj:type="object">
<object xj:name="Org" xj:type="string">COMPANY</object>
<object xj:name="Name" xj:type="string">NAME COMPANY</object>
<object xj:name="Version" xj:type="int">1</object>
</object>
</object>
<object xj:name="Payment" xj:type="object">
<object xj:name="PaymentId" xj:type="string">00000000-0000-0000-0000-943534532</object>
<object xj:name="Bill" xj:type="object">
<object xj:name="PaymentId" xj:type="string">00000000-0000-0000-0000-943534532</object>
<object xj:name="PaymeentNumber" xj:type="int">63703</object>
<object xj:name="BillId" xj:type="string">00000000-0000-0000-0000-003223439138</object>
</object>
</object>
Your stylesheet excludes the parent elements by the @xj:type != 'object'
predicate. Also, your method of:
<xsl:apply-templates select="//object"/>
will flatten the result. If you want to preserve the original hierarchy then try something like:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xj="http://camel.apache.org/component/xj"
exclude-result-prefixes="xj">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/object">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
<xsl:template match="object">
<xsl:choose>
<xsl:when test="@xj:name">
<xsl:element name="{@xj:name}">
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>