XSLT for-each newbie problem

R

R

Hello everybody.

I've got a problem with one loop.

Given XML:
<Types>
<Type><range>1</range><name>Gast</name></Type>
<Type><range>2</range><name>Rekt</name></Type>
<Type><range>2</range><name>Sigm</name></Type>
<!-- range is 1-6 -->
</Types>

I want to produce HTML output like this (grouped by range):
<li>Gast</li>
<li>Rekt, Sigm</li>

well I can produce the single <li> element for 'Gast and 'Rekt, Sigm'
output but I don't know how to iterate through all the 'range'

I did sth like:
1) produce <li> for range='1'
2) produce <li> for range='2'
....
6) produce <li> for range='6'

how to itrate through ranges from 1 to 6 automatically?
I know that ranges are sorted, there cannot be 5 before 2 etc.

this is my step-by-step version
<xsl:template match="Types" mode="searching">
<!-- do it for range='1' -->
<li>
<!-- variable needed for the comma -->
<xsl:variable name="last">
<xsl:value-of select="count(Type[./range='1'])"/></xsl:variable>
<xsl:for-each select="Type[./range='1']">
<xsl:value-of select="name"/>
<xsl:if test="$last != position()">, </xsl:if>
</xsl:for-each>
</li>
<li>
<xsl:variable name="last">
<xsl:value-of select="count(Type[./range='1'])"/></xsl:variable>
<xsl:for-each select="Type[./range='1']">
<xsl:value-of select="name"/>
<xsl:if test="$last != position()">, </xsl:if>
</xsl:for-each>
</li>
<!-- and for the rest of ranges 3, 4, 5, 6 the same -->
</xsl:template>

thanks for any help
best regards R
 
W

William Park

R said:
Hello everybody.

I've got a problem with one loop.

Given XML:
<Types>
<Type><range>1</range><name>Gast</name></Type>
<Type><range>2</range><name>Rekt</name></Type>
<Type><range>2</range><name>Sigm</name></Type>
<!-- range is 1-6 -->
</Types>

I want to produce HTML output like this (grouped by range):
<li>Gast</li>
<li>Rekt, Sigm</li>

Well, it's not XSLT, but this is what I would do using Expat parser and
Bash shell:

data () # Usage: data [1-6] or data [Gast|Rekt|...]
{
case ${XML_ELEMENT_STACK[1]} in
range) range=$1 ;;
name) name=$1 ;;
esac
}
start () # Usage: start tag att=value ...
{
case $1 in
Types) unset range{1..6} ;;
Type) unset range name ;;
esac
}
end () # Usage: end tag
{
case $1 in
Type) declare -p range$range &>/dev/null && strcat range$range ", "
strcat range$range $name ;;
esac
}

xml -s start -e end -d data '<Types> ... </Types>'
declare -p range{1..6}
 
B

Ben LamHang

Had a look at it. I tried using xsl:if / xml:when / xml:eek:therwise / xml:sort
to compare previous siblings and build the xml from there. However xml
doesn't like when you leave an unterminated tag which you need to run
through and stores 2 or more values between the same tags...
So close to your code, you have to manually put the figures in...

<?xml version="1.0" ?>
<xsl:transform version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="Types">
<li>
<xsl:for-each select="Type[range='1']">
<xsl:value-of select="name" /><xsl:if test="position()!=last()">,
</xsl:if>
</xsl:for-each>
</li>

<li>
<xsl:for-each select="Type[range='2']">
<xsl:value-of select="name" /><xsl:if test="position()!=last()">,
</xsl:if>
</xsl:for-each>
</li>

<li>
<xsl:for-each select="Type[range='3']">
<xsl:value-of select="name" /><xsl:if test="position()!=last()">,
</xsl:if>
</xsl:for-each>
</li>

<li>
<xsl:for-each select="Type[range='4']">
<xsl:value-of select="name" /><xsl:if test="position()!=last()">,
</xsl:if>
</xsl:for-each>
</li>

<li>
<xsl:for-each select="Type[range='5']">
<xsl:value-of select="name" /><xsl:if test="position()!=last()">,
</xsl:if>
</xsl:for-each>
</li>

<li>
<xsl:for-each select="Type[range='6']">
<xsl:value-of select="name" /><xsl:if test="position()!=last()">,
</xsl:if>
</xsl:for-each>
</li>
</xsl:template>

</xsl:transform>

R said:
Hello everybody.

I've got a problem with one loop.

Given XML:
<Types>
<Type><range>1</range><name>Gast</name></Type>
<Type><range>2</range><name>Rekt</name></Type>
<Type><range>2</range><name>Sigm</name></Type>
<!-- range is 1-6 -->
</Types>

I want to produce HTML output like this (grouped by range):
<li>Gast</li>
<li>Rekt, Sigm</li>

well I can produce the single <li> element for 'Gast and 'Rekt, Sigm'
output but I don't know how to iterate through all the 'range'

I did sth like:
1) produce <li> for range='1'
2) produce <li> for range='2'
...
6) produce <li> for range='6'

how to itrate through ranges from 1 to 6 automatically?
I know that ranges are sorted, there cannot be 5 before 2 etc.

this is my step-by-step version
<xsl:template match="Types" mode="searching">
<!-- do it for range='1' -->
<li>
<!-- variable needed for the comma -->
<xsl:variable name="last">
<xsl:value-of select="count(Type[./range='1'])"/></xsl:variable>
<xsl:for-each select="Type[./range='1']">
<xsl:value-of select="name"/>
<xsl:if test="$last != position()">, </xsl:if>
</xsl:for-each>
</li>
<li>
<xsl:variable name="last">
<xsl:value-of select="count(Type[./range='1'])"/></xsl:variable>
<xsl:for-each select="Type[./range='1']">
<xsl:value-of select="name"/>
<xsl:if test="$last != position()">, </xsl:if>
</xsl:for-each>
</li>
<!-- and for the rest of ranges 3, 4, 5, 6 the same -->
</xsl:template>

thanks for any help
best regards R
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top