I am using XSLT 1.0
Suppose I have an xml that has certain “num” elements that could be anywhere in an XML document like this :-
<elem1>
<num>24</num>
</elem1>
<elem2>
<description>
<num>18</num>
</description>
</elem2>
<elem3>
<elem1>
<num>36</num>
</elem1>
</elem3>
I want to convert it into :-
<elem1>
<gcd multiple="4">6</gcd>
</elem1>
<elem2>
<description>
<gcd multiple="3">6</gcd>
</description>
</elem2>
<elem3>
<elem1>
<gcd multiple="6">6</gcd>
</elem1>
</elem3>
Now I have a template that can compute gcd of two elements like this :-
<xsl:template name="gcd">
<xsl:param name="x"/>
<xsl:param name="y"/>
<!-- snipping code to compute gcd that goes here -->
</xsl:template>
Given this template for a gcd, I’m guessing that I will have to do something like loop over the num elements like this :-
<xsl:variable name="global_gcd">
<xsl:for-each select="//ns0:num">
<!-- something probably goes here -->
<!-- say a temporary value x=0 initially -->
<!-- and then x = gcd (x, value of current node) -->
</xsl:for-each>
</xsl:variable>
And then I can purportedly use this variable in my template for “num” to generate the desired “gcd” element along with attribute. That too I can do.
What should the above loop be like? If not a for-each, how would I actually compute the gcd of all the “num” elements in my XML document assuming I already have a working gcd template for two elements?
I suppose this would be a lot easier if I had all the “num” elements as siblings or something but unfortunately I don’t. The tree relationship between any two of these could potentially be arbitrary. The only thing I know, is that they all have the same name.
XSLT is a functional language, so there’s no concept of updatable variables – a variable has its value set when it is created, and that value cannot be changed subsequently. If you must do this in pure XSLT you’ll need to reformulate the problem as a recursive template instead of a loop
and call this template passing
//ns0:numas thenodesparam.But if you have the option of writing an extension function and plugging it in, that may be more efficient.