I would like to automate the elements based on input file expression.
My input file looks like
<?xml version="1.0" encoding="UTF-8"?>
<mappings>
<mapping inputContext="InputRoot" outputContext="outputRoot">
<input>InputParent/InputChild/InputSubChild</input>
<output>OutputParent/OPChild</output>
</mapping>
</mappings>
Based on above XML I had created the below XSLT
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns="http://www.testmapping.org/mapping">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="outputCtxt" select="mappings/mapping/output"/>
<xsl:call-template name="contextGenerator">
<xsl:with-param name="contextPath" select="$outputCtxt"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="contextGenerator">
<xsl:param name="contextPath" as="xs:string?"/>
<xsl:variable name="currentContext" select="substring-before($contextPath,'/')"/>
<xsl:variable name="subContext" select="substring-after($contextPath,'/')"/>
<xsl:element name="{$currentContext}">
<xsl:call-template name="contextGenerator">
<xsl:with-param name="contextPath" select="$subContext"/>
</xsl:call-template>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
I am expecting the output with below format
<outputRoot>
<OutputParent>
<OPChild></OPChild>
</OutputParent>
</outputRoot>
when I am trying to transform based on the input i am ending up with Expected QName error. Can I have the suggestions to address this issue.
The contextGenerator template is not properly splitting and recursing. (There is no / in the argument to contextGenerator on the second call, so the splits fail.)
Adding the following to the template helps show the problem:
<xsl:message>
[<xsl:value-of select="$currentContext"/>]
[<xsl:value-of select="$subContext"/>]
</xsl:message>
Output:
[OutputParent]
[OPChild]
[]
[]
The following replacement template produces the correct output:
<xsl:template name="contextGenerator">
<xsl:param name="contextPath" as="xs:string?"/>
<xsl:choose>
<xsl:when test="contains($contextPath, '/')">
<xsl:element name="{substring-before($contextPath, '/')}">
<xsl:variable name="subContext"
select="substring-after($contextPath, '/')"/>
<xsl:if test="$subContext">
<xsl:call-template name="contextGenerator">
<xsl:with-param name="contextPath" select="$subContext"/>
</xsl:call-template>
</xsl:if>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="{$contextPath}"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Result:
<OutputParent>
<OPChild/>
</OutputParent>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With