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.