[SOLVED] XSL If case with references in the Input XML

Issue

So this is a simplified Version of the Input XML:

<?xml version="1.0" encoding="UTF-8"?>
<Project>
    <RessourcePool>
        <Stock Ref="Ref_1" Name="135gl" Weight="135" WeightUnit="gsm"/>
        <Stock Ref="Ref_2" Name="300ma" Weight="300" WeightUnit="gsm"/>
    </RessourcePool>
    <Product Type="Bound">
        <StockRef rRef="Ref_1"/>
    </Product>
    <Product Type="Unbound">
        <StockRef rRef="Ref_2"/>
    </Product>
</Project>

Basically i started an XSL that goes through the Products and puts them into a new format, since there is a cross reference in the Input i couldn’t figure out how to put this into an if case or if theres a better solution for this. The starting XSL looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
        <xsl:for-each select="//Product">
                <xsl:variable name="elem-name">
                    <xsl:choose>
                        <xsl:when test='@Type="Bound"'>BoundComponent</xsl:when>
                        <xsl:otherwise>UnboundComponent</xsl:otherwise>
                    </xsl:choose>
                </xsl:variable>
                <xsl:element name="{$elem-name}">
                <!-- Now i want to add an attribute inside the element which is called "Material", therefore i want to check if the StockRef of the Product matches with one of the Stocks in the RessourcePool, if so it should take the @Name @Weight and @WeightUnit of the matching Stock and put it inside the Material Attribute like Material="135gl, 135gsm"-->
                </xsl:element>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Solution

I am guessing you want to do something like:

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:key name="stk" match="Stock" use="@Ref" />

<xsl:template match="/Project">
    <root>
        <xsl:for-each select="Product">
            <xsl:variable name="elem-name">
                <xsl:choose>
                    <xsl:when test="@Type='Bound'">BoundComponent</xsl:when>
                    <xsl:otherwise>UnboundComponent</xsl:otherwise>
                </xsl:choose>
            </xsl:variable>
            <xsl:element name="{$elem-name}">
                <xsl:variable name="stock" select="key('stk', StockRef/@rRef)" />
                <xsl:attribute name="Material">
                    <xsl:value-of select="$stock/@Name"/>
                    <xsl:text>, </xsl:text>
                    <xsl:value-of select="$stock/@Weight"/>
                    <xsl:value-of select="$stock/@WeightUnit"/>
                </xsl:attribute>
            </xsl:element>
        </xsl:for-each>
    </root>
</xsl:template>

</xsl:stylesheet>

Applied to your input example, this will produce:

Result

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <BoundComponent Material="135gl, 135gsm"/>
  <UnboundComponent Material="300ma, 300gsm"/>
</root>

Note that this assumes there is at most one Stock with the referenced Ref value.

Answered By – michael.hor257k

Answer Checked By – Robin (BugsFixing Admin)

Leave a Reply

Your email address will not be published.