问题
I have the following XSL script:
<xsl:for-each select="$AssignHistory/AssignmentHistory/*[name()=$week]/StudentItems/Item">
Student (or assistant): <xsl:value-of select="Name"/><br />
</xsl:for-each>
The actual XML StudentItems will have a varied number of items in it. Either:
1
7
14
21
If there are 7, then I want to show the list content like this:
1
2 / 3
4 / 5
6 / 7
If there are 14:
1
2 / 3
4 / 5
6 / 7
8
9 / 10
11 / 12
13 / 14
Finally, if there are 21:
1
2 / 3
4 / 5
6 / 7
8
9 / 10
11 / 12
13 / 14
15
16 / 17
18 / 19
20 / 21
At the moment I am just getting the varied "list" of names (understandably) but can I do the above? Example XML content:
<StudentItems>
<Item>
<Name Counsel="10">Matthew 1</Name>
<Type>Bible Reading (Main)</Type>
</Item>
<Item>
<Name Counsel="44">John 2</Name>
<Type>#1 Student (Main)</Type>
</Item>
<Item>
<Name>Robert 3</Name>
<Type>Assistant</Type>
</Item>
<Item>
<Name Counsel="38">Rachel 4</Name>
<Type>#2 Student (Main)</Type>
</Item>
<Item>
<Name>Aimie 5</Name>
<Type>Assistant</Type>
</Item>
<Item>
<Name Counsel="48">Julie 6</Name>
<Type>#3 Student (Main)</Type>
</Item>
<Item>
<Name>Diana 7</Name>
<Type>Assistant</Type>
</Item>
<Item>
<Name Counsel="5">Gordon 8</Name>
<Type>Bible Reading (Aux)</Type>
</Item>
<Item>
<Name Counsel="39">Sadie 9</Name>
<Type>#1 Student (Aux)</Type>
</Item>
<Item>
<Name>Bethany 1</Name>
<Type>Assistant</Type>
</Item>
<Item>
<Name Counsel="38">Zoe 2</Name>
<Type>#2 Student (Aux)</Type>
</Item>
<Item>
<Name>Angela 3</Name>
<Type>Assistant</Type>
</Item>
<Item>
<Name Counsel="37">Mary 4</Name>
<Type>#3 Student (Aux)</Type>
</Item>
<Item>
<Name>Kate 5</Name>
<Type>Assistant</Type>
</Item>
</StudentItems>
So where I mentioned a number, I am referring to the Item/Name in the list. Thank you for any assistance.
回答1:
I would suggest that instead of:
<xsl:for-each select="$AssignHistory/AssignmentHistory/*[name()=$week]/StudentItems/Item">
Student (or assistant): <xsl:value-of select="Name"/><br />
</xsl:for-each>
you do:
<xsl:apply-templates select="$AssignHistory/AssignmentHistory/*[name()=$week]/StudentItems"/>
Then add these templates:
<xsl:template match="StudentItems">
<xsl:apply-templates select="Item[not((position() - 1) mod 7) or ((position() - 1) mod 7) mod 2] "/>
</xsl:template>
<xsl:template match="Item">
<xsl:value-of select="Name"/>
<xsl:if test="(position() - 1) mod 4">
<xsl:apply-templates select="following-sibling::Item[1]" mode="follower"/>
</xsl:if>
<br/>
</xsl:template>
<xsl:template match="Item" mode="follower">
<xsl:text> / </xsl:text>
<xsl:value-of select="Name"/>
</xsl:template>
Would it be much work to tweak it so that on the line before 1 it says "Main" and on the line before 8 it says "Auxiliary Class 1" and on the line before 15 it says "Auxiliary Class 2"?
How about:
<xsl:template match="StudentItems">
<xsl:apply-templates select="Item[position() mod 7 = 1]" mode="leader"/>
</xsl:template>
<xsl:template match="Item" mode="leader">
<xsl:choose>
<xsl:when test="position() = 1">Main </xsl:when>
<xsl:when test="position() = 2">Auxiliary Class 1 </xsl:when>
<xsl:otherwise>Auxiliary Class 2 </xsl:otherwise>
</xsl:choose>
<xsl:value-of select="Name"/>
<br/>
<xsl:apply-templates select="following-sibling::Item[position() <= 6 and position() mod 2]"/>
</xsl:template>
<xsl:template match="Item">
<xsl:value-of select="Name"/>
<xsl:apply-templates select="following-sibling::Item[1]" mode="follower"/>
<br/>
</xsl:template>
<xsl:template match="Item" mode="follower">
<xsl:text> / </xsl:text>
<xsl:value-of select="Name"/>
</xsl:template>
回答2:
If I understand you correctly, if there is an assistant, then you want the name next to student. If there is no assistant, then you want just the student. Why don't you surround the <br/>
with an if-statement regarding the type? For example, like this:
<xsl-if test="Type='Assistant">
<xsl:value-of select="Name"/>
</xsl:if>
<xsl-if test="Type='Student'"><br/>
<xsl:value-of select="Name"/>
</xsl:if>
来源:https://stackoverflow.com/questions/35063212/selecting-specific-entries-in-a-for-each-loop