Variable in XSLT 3 with conditioning that returns the node name attribute if its child node contains specific name attribute

I would like to create a variable that will only be filled/populated if the child node of my node config has a specific name, in this case deviceName.

Here is an example of my input file:

<configs>
    <config name="CFAAI_CFA2" extends="CFAAI" abstract="true">
         <param name="deviceName">CFA2</param>
    </config>
</configs>

And here is the code I have so far for the variable:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no" />

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

<xsl:template match="config">
        <xsl:text>&#10;&#9;&#9;</xsl:text>
        <xsl:copy-of select="." />
        <xsl:variable name="namePrefix" >
            <xsl:choose>
                <xsl:when test="/param[@name='deviceName']">
                    <xsl:value-of select="config/@name"/>
                </xsl:when>
            </xsl:choose>
        </xsl:variable>
        <xsl:if
            test="not(contains(@name, 'TRANSFER') or contains(@extends, 'TRANSFER'))">
            <xsl:if
                test="count(. | //configs/config[starts-with(@name, $namePrefix)][1]) &lt;= 1">
                <xsl:if test="not(contains(@name, 'production'))">
                    <xsl:apply-templates select="."
                        mode="create_production">
                        <xsl:with-param name="productionName"
                            select="concat($namePrefix, '_production')" />
                    </xsl:apply-templates>
                </xsl:if>
            </xsl:if>
        </xsl:if>
    </xsl:template>

</xsl:stylesheet>

But my code is currently returning me an empty variable.

I would like my code to check if the attribute name of the child node /param equals deviceName and if it does I would like to select and return the value of its parent (the config node) name attribute.

Any suggestions on how could I do that inside a variable?

>Solution :

If you are in the context of config and you want to populate the variable only if a child param whose name is "deviceName" exists, then try:

<xsl:variable name="namePrefix" select="@name[../param/@name='deviceName']" />

or, if you prefer:

<xsl:variable name="namePrefix" select="if (param[@name='deviceName']) then @name else ''" />

Note that there is a difference between populating a variable using the select attribute vs. using a sequence constructor. In the former case the variable will contain a value, in the latter a node.

Leave a Reply