Creating new attribute based on another attribute value in XML using XSLT
Posted: Mon Apr 04, 2022 10:45 am
I need this input xml file :
(The ... are for generalizing the input xml so that more phases and apps sections can be added.)
to be transformed to this output xml file :
So, in the input file when I have <attribute name="type" value="apps jump" /> I need to add <attribute name="app_name" value="entryvalue1" /> right after <attribute name="type" value="apps jump" />. And when I have <attribute name="type" value="phases2" /> or <attribute name="type" value="phases3" /> or ANY VALUE in value="" in <attribute name="type"> other than "apps jump" then I need to add <attribute name="phase_name" value="entryvalue2" /> right after the attribute with type element i.e. for the 2nd case <attribute name="type" value="phases2" />.
Also, the value in <attribute name="app_name" value="entryvalue1" /> and <attribute name="phase_name" value="entryvalue2" /> and so on, holds the value of their corresponding entryMap name value.
Here for this example I have 1 app and 2 phase sections with app defined first and then the 2 phases are defined but that is not fixed. I can have multiple app and phase sections in any position in my input xml but on the same level. So I'm trying to create a generalized XSLT which will work on any number of app and phase sections.
The current sample XSLT I have right now is this :
If someone could please help me out with this, I'd be very grateful.
Code: Select all
<response>
<ActionValue>
<entryMap name="entryvalue1">
<action>
<attribute name="type" value="apps jump" />
</action>
</entryMap>
<entryMap name="entryvalue2">
<action>
<attribute name="type" value="phases2" />
</action>
</entryMap>
<entryMap name="entryvalue3">
<action>
<attribute name="type" value="phases3" />
</action>
</entryMap>
<entryMap name="...">
<action>
<attribute name="type" value="..." />
</action>
</entryMap>
</ActionValue>
</response>
to be transformed to this output xml file :
Code: Select all
<response>
<ActionValue>
<entryMap name="entryvalue1">
<action>
<attribute name="type" value="apps jump" />
<attribute name="app_name" value="entryvalue1" />
</action>
</entryMap>
<entryMap name="entryvalue2">
<action>
<attribute name="type" value="phases2" />
<attribute name="phase_name" value="entryvalue2" />
</action>
</entryMap>
<entryMap name="entryvalue3">
<action>
<attribute name="type" value="phases3" />
<attribute name="phase_name" value="entryvalue3" />
</action>
</entryMap>
<entryMap name="...">
<action>
<attribute name="type" value="..." />
<attribute name="..." value="..." />
</action>
</entryMap>
</ActionValue>
</response>
Also, the value in <attribute name="app_name" value="entryvalue1" /> and <attribute name="phase_name" value="entryvalue2" /> and so on, holds the value of their corresponding entryMap name value.
Here for this example I have 1 app and 2 phase sections with app defined first and then the 2 phases are defined but that is not fixed. I can have multiple app and phase sections in any position in my input xml but on the same level. So I'm trying to create a generalized XSLT which will work on any number of app and phase sections.
The current sample XSLT I have right now is this :
Code: Select all
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- Identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="action">
<xsl:copy>
<xsl:copy-of select="*"/>
<attribute name="phase_name" value="{../@name}"/>
<attribute name="app_name" value="{../@name}"/>
</xsl:copy>
</xsl:template>
<xsl:template match="action">
<xsl:for-each select="attribute">
<xsl:if test="@name='phase_name'">
<xsl:value-of select="@value"/>
</xsl:if>
<xsl:if test="@name='app_name'">
<xsl:value-of select="@value"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>