Home > Blockchain >  XSLT Ignoring variable selection and conditioning and execuing everything
XSLT Ignoring variable selection and conditioning and execuing everything

Time:05-09

Within my code I have the current problem. I'm trying to return the value of the Attribute "version" from the "config" element and using it to make a condition.

If version = "2" it should execute the template "c-stage" and if it starts with "$" it should then remove the dolar sign, save it to a vairable, compare it to the variables on the XML folder, if the variable when comparingequals to "2", then run the template "c-stage". If the element "config" has no "version" attribute it looks within the node hierarchy for the parents "version".

Currently this is my code:

<?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="yes" />

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

   <!-- c-condition -->

   <xsl:template match="//config" mode="c-check">
       <xsl:variable name="versionspec">
           <xsl:apply-templates select="." mode="c-condition" />
       </xsl:variable>
       <xsl:variable name="staged">
           <xsl:choose>
               <xsl:when test="starts-with($versionspec, '2.')">
                   <xsl:value-of select="$versionspec" />
               </xsl:when>
               <xsl:otherwise />
           </xsl:choose>
       </xsl:variable>
       <xsl:choose>
           <xsl:when test="$staged">
               <xsl:copy>
                   <xsl:apply-templates select="." mode="c-staged" />
               </xsl:copy>
           </xsl:when>
           <xsl:otherwise>
               <xsl:copy>
                   <xsl:apply-templates select="." mode="c-non-staged" />
               </xsl:copy>
           </xsl:otherwise>
       </xsl:choose>
   </xsl:template>

   <xsl:template match="config" mode="c-condition">
       <xsl:message>
           Foo!
           <xsl:value-of select="@name" />
       </xsl:message>
       <xsl:choose>
           <xsl:when test="@version">
               <xsl:choose>
                   <xsl:when test="starts-with(translate(@version, '0123456789', '9999999999'), '9')">
                       <xsl:value-of select="." />
                   </xsl:when>
                   <xsl:when test="starts-with(@version, '$')">
                       <xsl:variable name="variableName">
                           <xsl:call-template name="remove">
                               <xsl:with-param name="value" select="." />
                           </xsl:call-template>
                       </xsl:variable>
                       <!-- strip the dollar sign an braces and assign the result to a variable "variableName" -->
                       <xsl:apply-templates select="//variable[@name = $variableName]" mode="c-condition" />
                   </xsl:when>
                   <xsl:otherwise />
               </xsl:choose>
               <!-- find versionSpec -->
           </xsl:when>
           <xsl:otherwise>
               <xsl:if test="@extension">
                   <xsl:variable name="extension" select="@extension" />
                   <xsl:apply-templates select="//config[@name=$extension]" mode="c-condition" />
               </xsl:if>
           </xsl:otherwise>
       </xsl:choose>
   </xsl:template>


   <xsl:template match="config" mode="c-staged">
       <!-- CHECKS CURRENT STAGE -->
       <xsl:choose>
           <xsl:when test="contains(@name, 'release')">
               <xsl:copy>
                   <xsl:copy-of select="@*" />
                   <xsl:attribute name="stage">RELEASE</xsl:attribute>
                   <xsl:copy-of select="*" />
               </xsl:copy>
           </xsl:when>
           <xsl:when test="contains(@name, 'test')">
               <xsl:copy>
                   <xsl:copy-of select="@*" />
                   <xsl:attribute name="stage">TEST</xsl:attribute>
                   <xsl:copy-of select="*" />
               </xsl:copy>
           </xsl:when>
           <xsl:otherwise>
               <xsl:copy>
                   <xsl:copy-of select="@*|*" />
               </xsl:copy>
           </xsl:otherwise>
       </xsl:choose>
   </xsl:template>


   <xsl:template match="config" mode="c-non-staged">
       <xsl:copy>
           <xsl:copy-of select="@*|*" />
       </xsl:copy>
   </xsl:template>

   <xsl:template match="variable" mode="c-condition">
       <xsl:value-of select="text()" />
   </xsl:template>

   <xsl:template name="remove">
       <xsl:param name="value" />
       <xsl:value-of select="concat(substring-before($value, '$['), substring-after($value, ']'))" />
   </xsl:template>

</xsl:stylesheet> 

And this is my XML file:

<?xml version="1.0" encoding="UTF-8"?>

<?xml-stylesheet type="text/xsl" href="Launcher.xsl"?>

<launcherConfig>
    <variables>
        <variable name="productionVersion">1.23</variable>
        <variable name="productionPriority">0</variable>
        
        <variable name="releaseSITEVersion">1.1.214c</variable> 
        <variable name="testSITEVersion">1.1</variable> 
        
        <variable name="testSITEVersion4294_RC1">1.4.254</variable> 
        <variable name="testSITEVersion4607">-1.1</variable> 
        <variable name="testSITEVersion5210">1.6</variable> 
        <variable name="testSITEVersion5227_Fix">1.7.2702</variable>
        <variable name="testSITEVersion5344">true</variable>
        <variable name="testSITEVersion5682">1.3.3418</variable>
        <variable name="testSITEVersionALTRAP5693">1.8</variable>

        
        <variable name="testSITEVersion4856">foo.1.2146</variable>
        <variable name="testSITEVersion5227">1.1.2530</variable>
    </variables>
    <configs>
        
        <config name="1_TEST_FOO" extends="1" abstract="true" version="1">
        </config>
        <config name="1_TEST_FOO_release" extends="1_TEST_FOO">     
        </config>
        <config name="1_TEST_FOO_test" extends="1_TEST_FOO" version="${testSITEVersion5227}">   
        </config>
        
        <config name="2_TEST_FOO" extends="2" abstract="true">
        </config>
        <config name="2_TEST_FOO_release" extends="2_TEST_FOO" version="2.0" >          
        </config>
        <config name="2_TEST_FOO_test" extends="2_TEST_FOO" version="${testSITEVersion5227}">           
        </config>
        
        <config name="3_TEST_FOO" extends="3" abstract="true" version="${releaseSITEVersion}">
        </config>
        <config name="3_TEST_FOO_release" extends="3_TEST_FOO" >
        </config>
        <config name="3_TEST_FOO_test" extends="3_TEST_FOO">            
        </config> 
   </configs>
</launcherConfig>

From my point of view my code should work just fine but (I'm quite new to XSL) and it currently ignores all conditioning and just executes the "c-stage" directly even ignoring the version. Delivering me this:

<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="Launcher.xsl"?><launcherConfig>
        
        1.23
        0
        
        1.1.214c 
        1.1 
        
        1.4.254 
        -1.1 
        1.6 
        1.7.2702
        true
        1.3.3418
        1.8

        
        foo.1.2146
        1.1.2530
    

    
        
        
    <config>
        <config name="1_TEST_FOO" extends="1" abstract="true" version="1"/>
    </config>
            
    <config>
        <config name="1_TEST_FOO_release" extends="1_TEST_FOO" stage="RELEASE"/>
    </config>
            
    <config>
        <config name="1_TEST_FOO_test" extends="1_TEST_FOO" version="${testSITEVersion5227}" stage="TEST"/>
    </config>
            
        
    <config>
        <config name="2_TEST_FOO" extends="2" abstract="true"/>
    </config>
            
    <config>
        <config name="2_TEST_FOO_release" extends="2_TEST_FOO" version="2.0" stage="RELEASE"/>
    </config>
            
    <config>
        <config name="2_TEST_FOO_test" extends="2_TEST_FOO" version="${testSITEVersion5227}" stage="TEST"/>
    </config>
            
        
    <config>
        <config name="3_TEST_FOO" extends="3" abstract="true" version="${releaseSITEVersion}" stage="TEST"/>
    </config>
            
    <config>
        <config name="3_TEST_FOO_release" extends="3_TEST_FOO" stage="RELEASE"/>
    </config>
            
    <config>
        <config name="3_TEST_FOO_test" extends="3_TEST_FOO" stage="TEST"/>
    </config>
        

</launcherConfig>

It just adds the attribute “stage” to each of them without following proper conditioning.

I would like to know what am I doing wrong and how can I fix it?

Maybe the title is not the best, StackOverflow and XSLT noobie here

CodePudding user response:

I haven't looked at the logic in detail, but:

   <xsl:variable name="staged">
       <xsl:choose>
           <xsl:when test="starts-with($versionspec, '2.')">
               <xsl:value-of select="$versionspec" />
           </xsl:when>
           <xsl:otherwise />
       </xsl:choose>
   </xsl:variable>

in the absence of an "as" attribute on xsl:variable, the variable is a document node, and therefore <xsl:when test="$staged"> is always true.

I'm not sure what type you wanted $staged to be, but it's best - for readability, debugability, performance, and reliability - to declare it in an @as attribute.

  • Related