I have a source document with a structure which is basically like this:
<data>
<fruits>
<orange>orangeinfo</orange>
<apple>appleinfo</apple>
<apple>appleinfo</apple>
<orange>orangeinfo</orange>
<pear>pearinfo</pear>
</fruits>
</data>
* The document order is not necessarily the same as the output order.
* The output order requires each fruit type to be grouped together, and each of these subsets to be output in a particular order (let's say pears then apples then oranges).
* It is not necessary that any one fruit type is represented at all in the data (i.e. could be just apples and pears).
* The output is formatted like in this style: (pearinfo, appleinfo, appleinfo, orangeinfo, orangeinfo)
1) In my first attempt I asked questions of each node() as I go through a for-each loop, add the relevant seperators and paste in the value-of. This constructs the ( , , , ) structure correctly, but does not group the data at all. Altering the order in the for-each select expression does not affect the way the nodeset is created (document order). Thus the output is in document order:
<code>
<xsl:for-each select="orange | apple | pear">
<xsl:choose>
<xsl:when test="position()=1 and position()=last()">
<xsl:text> (</xsl:text>
<xsl:value-of select="."/>
<xsl:text>)</xsl:text>
</xsl:when>
<xsl:when test="position()=1">
<xsl:text> (</xsl:text>
<xsl:value-of select="."/>
<xsl:text>, </xsl:text>
</xsl:when>
<xsl:when test="position()=last()">
<xsl:value-of select="."/>
<xsl:text>)</xsl:text>
</xsl:when>
<xsltherwise>
<xsl:value-of select="."/>
<xsl:text>, </xsl:text>
</xsltherwise>
</xsl:choose>
</xsl:for-each>
</code>
2) My second approach was to use an apply-templates code. This groups the fruits together, but I do not keep track of where I am within the nodeset and in this case it leaves me with an undesired comma after the final orange, before the closing paranthesis. Essentially I cannot distinguish my first and final fruits for special treatment because I do not know what type of fruit they may be:
<code>
<xsl:template match="fruits">
<xsl:text> (</xsl:text>
<xsl:apply-templates select="pears"/>
<xsl:apply-templates select="apples"/>
<xsl:apply-templates select="oranges"/>
<xsl:text>) </xsl:text>
</xsl:template>
<xsl:template match="*">
<xsl:value-of select="."/>
<xsl:text>, </xsl:text>
</xsl:template>
</code>
Can anyone help with this problem? A solution using either approach is satisfactory, or a totally different approach if there is one and/or it is necessary.
Thanks
<data>
<fruits>
<orange>orangeinfo</orange>
<apple>appleinfo</apple>
<apple>appleinfo</apple>
<orange>orangeinfo</orange>
<pear>pearinfo</pear>
</fruits>
</data>
* The document order is not necessarily the same as the output order.
* The output order requires each fruit type to be grouped together, and each of these subsets to be output in a particular order (let's say pears then apples then oranges).
* It is not necessary that any one fruit type is represented at all in the data (i.e. could be just apples and pears).
* The output is formatted like in this style: (pearinfo, appleinfo, appleinfo, orangeinfo, orangeinfo)
1) In my first attempt I asked questions of each node() as I go through a for-each loop, add the relevant seperators and paste in the value-of. This constructs the ( , , , ) structure correctly, but does not group the data at all. Altering the order in the for-each select expression does not affect the way the nodeset is created (document order). Thus the output is in document order:
<code>
<xsl:for-each select="orange | apple | pear">
<xsl:choose>
<xsl:when test="position()=1 and position()=last()">
<xsl:text> (</xsl:text>
<xsl:value-of select="."/>
<xsl:text>)</xsl:text>
</xsl:when>
<xsl:when test="position()=1">
<xsl:text> (</xsl:text>
<xsl:value-of select="."/>
<xsl:text>, </xsl:text>
</xsl:when>
<xsl:when test="position()=last()">
<xsl:value-of select="."/>
<xsl:text>)</xsl:text>
</xsl:when>
<xsltherwise>
<xsl:value-of select="."/>
<xsl:text>, </xsl:text>
</xsltherwise>
</xsl:choose>
</xsl:for-each>
</code>
2) My second approach was to use an apply-templates code. This groups the fruits together, but I do not keep track of where I am within the nodeset and in this case it leaves me with an undesired comma after the final orange, before the closing paranthesis. Essentially I cannot distinguish my first and final fruits for special treatment because I do not know what type of fruit they may be:
<code>
<xsl:template match="fruits">
<xsl:text> (</xsl:text>
<xsl:apply-templates select="pears"/>
<xsl:apply-templates select="apples"/>
<xsl:apply-templates select="oranges"/>
<xsl:text>) </xsl:text>
</xsl:template>
<xsl:template match="*">
<xsl:value-of select="."/>
<xsl:text>, </xsl:text>
</xsl:template>
</code>
Can anyone help with this problem? A solution using either approach is satisfactory, or a totally different approach if there is one and/or it is necessary.
Thanks