Creating new attribute based on another attribute value in XML using XSLT
Here should go questions about transforming XML with XSLT and FOP.
-
- Posts: 1
- Joined: Mon Apr 04, 2022 10:29 am
Creating new attribute based on another attribute value in XML using XSLT
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>
Last edited by user05 on Tue Apr 05, 2022 6:59 pm, edited 1 time in total.
-
- Posts: 9424
- Joined: Fri Jul 09, 2004 5:18 pm
Re: Creating new attribute based on another attribute value in XML using XSLT
Hi,
Maybe something like this would work:
Regards,
Radu
Maybe something like this would work:
Code: Select all
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="attribute[@name='type']">
<!-- Copy current element as it is -->
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="node()"/>
</xsl:copy>
<xsl:choose>
<xsl:when test="@value='apps jump'">
<attribute name="app_name" value="{ancestor::entryMap/@name}" />
</xsl:when>
<xsl:otherwise>
<attribute name="phase_name" value="{ancestor::entryMap/@name}" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
<oXygen/> XML Editor
http://www.oxygenxml.com
Jump to
- Oxygen XML Editor/Author/Developer
- ↳ Feature Request
- ↳ Common Problems
- ↳ DITA (Editing and Publishing DITA Content)
- ↳ SDK-API, Frameworks - Document Types
- ↳ DocBook
- ↳ TEI
- ↳ XHTML
- ↳ Other Issues
- Oxygen XML Web Author
- ↳ Feature Request
- ↳ Common Problems
- Oxygen Content Fusion
- ↳ Feature Request
- ↳ Common Problems
- Oxygen JSON Editor
- ↳ Feature Request
- ↳ Common Problems
- Oxygen PDF Chemistry
- ↳ Feature Request
- ↳ Common Problems
- Oxygen Feedback
- ↳ Feature Request
- ↳ Common Problems
- Oxygen XML WebHelp
- ↳ Feature Request
- ↳ Common Problems
- XML
- ↳ General XML Questions
- ↳ XSLT and FOP
- ↳ XML Schemas
- ↳ XQuery
- NVDL
- ↳ General NVDL Issues
- ↳ oNVDL Related Issues
- XML Services Market
- ↳ Offer a Service