Reputation: 1
We have a xml which needs to be transformed using XSLT. But, we have to add two attributes of a tag and place it in other tag.
In below XML compilation tag with column 'Reusable' has values contrib and max_available. We want addition of these two attributes and want it in the attribute postPosition of compilation tag with column "Usable". Now, we have additional requirement to add on the basis of fac value as well.
Input
<?xml version="1.0" encoding="UTF-8"?>
<answers user="LST">
<answer name="compile">
<output>
<compilations>
<compilation column="Usable" fac="123" contrib="0" max_available="0" postPosition="35000">
</compilation>
<compilation column="Usable" fac="456" contrib="0" max_available="0" postPosition="35000">
</compilation>
<compilation column="ReUsable" fac="123" contrib="0" max_available="200" postPosition="300">
</compilation>
<compilation column="Reusable" fac="456" contrib="100.00" postPosition="100.00" max_available="200">
</compilation>
</compilations>
</output>
</answer>
</answers>
Output :
<?xml version="1.0" encoding="UTF-8"?>
<answers>
<answer name="compile">
<output>
<compilations>
<compilation column="Usable" fac="123" contrib="0" max_available="0" postPosition="500">
</compilation>
<compilation column="Usable" fac="456" contrib="0" max_available="0" postPosition="300">
</compilation>
<compilation column="ReUsable" fac="123" contrib="0" max_available="200" postPosition="300">
</compilation>
<compilation column="Reusable" fac="456" contrib="100.00" postPosition="100.00" max_available="200">
</compilation>
</compilations>
</output>
</answer>
</answers>
Upvotes: 0
Views: 1858
Reputation: 117140
How about simply:
XSLT 2.0
<xsl:stylesheet version="2.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="compilation[@column='Usable']/@postPosition">
<xsl:attribute name="postPosition" select="format-number(../../compilation[@column='Reusable']/(@contrib + @max_available), '0.00')" />
</xsl:template>
</xsl:stylesheet>
Note that this assumes there is only one compilation
with a 'Reusable' column
in a compilations
element.
To do the same thing in XSLT 1.0:
<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="compilation[@column='Usable']/@postPosition">
<xsl:variable name="reusable" select="../../compilation[@column='Reusable']" />
<xsl:attribute name="postPosition">
<xsl:value-of select="format-number($reusable/@contrib + $reusable/@max_available, '0.00')" />
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1
Reputation: 4749
Following XSLT will copy the Usable compilation and change the value of the postPosition attribute:
<?xml version="1.0" encoding="UTF-8"?>
<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="compilation[@column='Usable']">
<xsl:copy>
<!-- copy other attributes first -->
<xsl:apply-templates select="@column"/>
<xsl:apply-templates select="@contrib"/>
<xsl:apply-templates select="@max_available"/>
<!-- set the postPosition attribute -->
<xsl:attribute name="postPosition">
<xsl:variable name="reusableCompilation" select="../compilation[@column='Reusable']"/>
<xsl:value-of select="number($reusableCompilation/@contrib)+number($reusableCompilation/@max_available)"></xsl:value-of>
</xsl:attribute>
<!-- copy all child elements -->
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<!-- generic template - copy all the rest -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
This will give you following output with the sumb of both attributes @contrib + @max_available:
<?xml version="1.0" encoding="UTF-8"?>
<answers>
<answer name="compile">
<output>
<compilations>
<compilation column="Usable" contrib="0" max_available="0" postPosition="300">
</compilation>
<compilation column="Reusable" contrib="100.00" postPosition="100.00" max_available="200">
</compilation>
</compilations>
</output>
</answer>
</answers>
Upvotes: 0