我是XSL的新手,试图为我做一些有点复杂的事情,并寻求帮助。
以下是XML可能的样子:
<foo>
<customers>
<customer>
<title>Ms</title>
<name>
<firstName>Jane</firstName>
<lastName>Customer</lastName>
</name>
<reservations>
<reseration>
<reservationNumber>123</reservationNumber>
<reservationDate>2013-02-15</reservationDate>
<table>12</table
</reservation>
<reseration>
<reservationNumber>456</reservationNumber>
<reservationDate>2013-03-24</reservationDate>
<table>09</table
</reservation>
<reseration>
<reservationNumber>789</reservationNumber>
<reservationDate>2013-05-02</reservationDate>
<table>22</table
</reservation>
</reservations>
</customer>
<customer>
<title>Dr</title>
<name>
<firstName>John</firstName>
<lastName>Smith</lastName>
</name>
<reservations>
<reseration>
<reservationNumber>ABC</reservationNumber>
<reservationDate>2013-02-15</reservationDate>
<table>05</table
</reservation>
<reseration>
<reservationNumber>DEF</reservationNumber>
<reservationDate>2013-03-24</reservationDate>
<table>10</table
</reservation>
<reseration>
<reservationNumber>GHI</reservationNumber>
<reservationDate>2013-05-02</reservationDate>
<table>16</table
</reservation>
</reservations>
</customer>
</customers>
</foo>
我希望结果表看起来像这样:
Title Name Reservation Date Table
----- ---- ----------- ---- -----
Ms Jane Customer 123 2013-02-15 12
456 2013-03-24 09
789 2013-05-02 22
Dr John Smith ABC 2013-02-15 05
DEF 2013-03-24 10
GHI 2013-05-02 16
我知道如何使用XSL for-each构建每一行来构建一个表。这有什么棘手的问题是如何构建递归,将第一个子元素的预留细节(预留,日期和表格)拉到与第一行的父元素相同的行中。然后只剩下其余行中剩余子元素的预留详细信息。
所以这个:
Title Name Reservation Date Table
----- ---- ----------- ---- -----
Ms Jane Customer 123 2013-02-15 12
456 2013-03-24 09
789 2013-05-02 22
不是这个:
Title Name Reservation Date Table
----- ---- ----------- ---- -----
Ms Jane Customer
123 2013-02-15 12
456 2013-03-24 09
789 2013-05-02 22
进行了大量搜索,并没有看到任何类似的内容。
更新
这是我能够上班的事情
<xsl:for-each select="customers/customer">
<xsl:for-each select="./reservations/reservation">
<xsl:choose>
<xsl:when test="position() = 1">
<tr>
<td><xsl:value-of select="../../title"/></td>
<td><xsl:value-of select="reservationNumber"/></td>
</tr>
</xsl:when>
....
答案 0 :(得分:2)
最简单的方法可能是仅匹配reservation
元素。
对于每个reservation
,您可以使用<xsl:when test="node[position() > 1]">
来测试每个是否是其父级的第一个子级。如果是,您可以使用parent
轴来获取customer
详细信息;否则,你可以用空白填充。
答案 1 :(得分:0)
如果要使标题和名称跨越多行,可以使用count()
功能查找预订数量。
您需要以不同于其他方式处理第一个预订,因为第一个预订会在同一个表格行上进行。
以下片段说明了这个想法:
<xsl:template match="customer">
<xsl:variable name="res" select="reservations/reservation"/>
<tr>
<td rowspan="{count($res)}"><xsl:value-of select="title"/></td>
<td rowspan="{count($res)}"><xsl:apply-templates select="name"/></td>
<!-- the first reservation goes to the same row -->
<xsl:apply-templates select="$res[1]"/>
</tr>
<!-- the rest of the reservations go to their own rows -->
<xsl:for-each select="$res[position() > 1]">
<tr>
<xsl:apply-templates select="."/>
</tr>
</xsl:for-each>
</xsl:template>
<xsl:template match="name">
<xsl:value-of select="concat(firstName, ' ', lastName)"/>
</xsl:template>
<xsl:template match="reservation">
<td><xsl:value-of select="reservationNumber"/></td>
<td><xsl:value-of select="reservationDate"/></td>
<td><xsl:value-of select="table"/></td>
</xsl:template>