I normally use String-join() functions extensively for handling and joining values coming from Database, however currently I observed if the second variable of the function is first fetched/present in the XSL/XML structure than the first variable, then the output is reversed of that expected value. For example:
<?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" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" exclude-result-prefixes="#all" version="3.0">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="/">
<xsl:variable name="b">
<row>
<value>2</value>
</row>
</xsl:variable>
<xsl:variable name="a">
<row>
<value>1</value>
</row>
</xsl:variable>
<xsl:variable name="c">
<row>
<value>1</value>
</row>
</xsl:variable>
<xsl:variable name="d">
<row>
<value>2</value>
</row>
</xsl:variable>
<!-- Version a-->
<xsl:value-of select="string-join(($a,$b)[. != '']/row/value/text(), ';')"/>
<!-- OP - 2;1 -->
<!-- Version b-->
<xsl:value-of select="formatter:crlf()"/>
<xsl:value-of select="string-join(($c,$d)[. != '']/row/value/text(), ';')"/>
<!-- OP - 1;2 -->
<!-- Version c-->
<xsl:value-of select="formatter:crlf()"/>
<xsl:value-of select="string-join(($a[. != '']/row/value/text(),$b[. != '']/row/value/text()), ';')"/>
<!-- OP - 1;2 -->
</xsl:template>
</xsl:stylesheet>
Here, I have four variables a, b, c, d with values 1, 2, 1, 2 respectively and 3 versions of string-join() function. With the first version a I get output 2;1 which is not what I was expecting and it seems since b was declared before a, when fetching the value, b was fetched earlier and in that order it was joined and printed. With version b, I get the expected since c is declared before d. With version c, I did a tweak and was now able to get the correct sequence.
My expectation is that this should NOT happen. In real production scenarios I have many values coming from DBs which are fetched asynchronously and when needed so when I perform string-join() operation I expect the correct output.
I verified this is not due to SAXON or XPATH issue, since I tried both SAXON 10 with XPATH 3 & SAXON 9 with XPATH 2 and was getting the same result.
Let me know what you guys think and what can I do?
You are using the /
operator which sorts nodes in document order so in string-join(($a,$b)[. != '']/row/value/text(), ';')
, while you define an order $a,$b
, the use of /row/value/text()
ensures that document order is used, only that I think document order for nodes from different documents is basically undefined.
You can use !
instead of /
e.g. <xsl:value-of select="string-join(($a,$b)[. != '']!row!value!text(), ';')"/>
.