我有这个xml代码
<realtime_result>
<team>
<team_name>real madrid</team_name>
<events>
<yellow_card time="28">ronaldo</yellow_card>
<yellow_card time="31">ronaldo</yellow_card>
<red_card time="39">benzema</red_card>
.
.
</events>
</team>
<team>
<team_name>Barcelona</team_name>
<events>
<goal time="25">messi</goal>
<red_card time="44">messi</red_card>
<yellow_card time="63">iniesta</yellow_card>
.
.
</events>
</team>
</realtime_result>
我需要一个xslt代码将其转换为这样的表:
<table>
<tr>
<th>real madrid</th>
<th>time</th>
<th>barcelona</th>
</tr>
<tr>
<td></td>
<td>25</td>
<td>goal : messi</td>
</tr>
<tr>
<td>yello card : ronaldo</td>
<td>28</td>
<td>barcelona</td>
</tr>
.
.
<table>
请注意事件已排序(25,28,31,39,44 ......)。
任何人都可以帮助我吗? 非常感谢。
答案 0 :(得分:1)
您的示例输入XML无效 - 缺少第一个结束team
标记,第二个团队的事件具有错误的结束标记。此外,所需的输出有点不清楚 - 第一个事件不会显示团队名称,而第二个事件则显示。我猜团队名称不应该显示,因为它已经在标题中,遵循XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="realtime_result">
<table>
<tr>
<th>
<xsl:value-of select="//team[1]/team_name"/>
</th>
<th>time</th>
<th>
<xsl:value-of select="//team[2]/team_name"/>
</th>
</tr>
<xsl:apply-templates select="//events/*">
<xsl:sort select="@time"/>
</xsl:apply-templates>
</table>
</xsl:template>
<xsl:template match="*">
<tr>
<td>
<xsl:if test="
parent::events/preceding-sibling::team_name
[
normalize-space()='real madrid'
]">
<xsl:value-of select="concat(local-name(),' : ', .)"/>
</xsl:if>
</td>
<td><xsl:value-of select="@time"/></td>
<td>
<xsl:if test="
parent::events/preceding-sibling::team_name
[
normalize-space()='Barcelona'
]">
<xsl:value-of select="concat(local-name(),' : ', .)"/>
</xsl:if>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
当应用于更正的输入时,XML具有输出
<table>
<tr>
<th>real madrid</th>
<th>time</th>
<th>Barcelona</th>
</tr>
<tr>
<td></td>
<td>25</td>
<td>goal : messi</td>
</tr>
<tr>
<td>yellow_card : ronaldo</td>
<td>28</td>
<td></td>
</tr>
<tr>
<td>yellow_card : ronaldo</td>
<td>31</td>
<td></td>
</tr>
<tr>
<td>red_card : benzema</td>
<td>39</td>
<td></td>
</tr>
<tr>
<td></td>
<td>44</td>
<td>red_card : messi</td>
</tr>
<tr>
<td></td>
<td>63</td>
<td>yellow_card : iniesta</td>
</tr>
</table>
在将模板应用于事件时,使用<xsl:sort select="@time"/>
按时间对事件进行排序。生成行的模板使用
<xsl:if test="parent::events/preceding-sibling::team_name
[
normalize-space()='Barcelona'
]">
由于输入XML在team_name
上没有任何空格,因此也可以写为
<xsl:if test="parent::events/preceding-sibling::team_name
[
.='Barcelona'
]">
normalize-space()
只会删除检查相等时有时需要的任何前导或尾随空格
事件单元格的值仅针对当前事件的团队编写,并使用local-name()
检索事件名称。
供参考:xsl:sort,local-name(),normalize-space(),以及XPath轴的http://www.xmlplease.com/axis
可能有用的可视化作为旁注 - 虽然你的问题被一些成员低估了,因为正如你在评论中注意到的那样,它没有显示任何先前的努力,我只是想给你一个答案,因为你已经是1的SO成员了半年,这是你的第一个问题。对于即将出现的问题,最好包括您已尝试寻找解决方案或将问题减少到特定问题,而不是询问如何为输入X获取输出Y.如一条评论中所述,您可能会考虑使用看看https://stackoverflow.com/help/how-to-ask