我是XSLT的新手,我有一个像这样的XML;
<TerminalRoutes>
<Segment>
<From>
<previous>DEN </previous>
<current>DNV</current>
</From>
<From>
<previous>LAX </previous>
<current>LAS</current>
</From>
</Segment>
<Segment>
<To>
<previous>ATL </previous>
<current>ATN</current>
</To>
<To>
<previous>JFK</previous>
<current>LGA </current>
</To>
</Segment>
</TerminalRoutes>
我正在尝试使用XSLT将XML转换为HTML,并且我正在应用此模板
<xsl:template match="TerminalRoutes">
<tr>
<td>
<b>Terminal Routes</b>
</td>
<td> </td>
<td> </td>
</tr>
<tr>
<td>TERMINAL ROUTES FROM</td>
<td>
<xsl:value-of select="Segment/From/previous"></xsl:value-of>
</td>
<td>
<xsl:value-of select="Segment/From/current"></xsl:value-of>
</td>
</tr>
<tr>
<td>TERMINAL ROUTES TO</td>
<td>
<xsl:value-of select="Segment/To/previous"></xsl:value-of>
</td>
<td>
<xsl:value-of select="Segment/To/current"></xsl:value-of>
</td>
</tr>
</xsl:template>
并且得到的HTML给了我第一个结果集,即第一个&#34; From&#34;和第一个&#34; To&#34;。
我想要的是重新应用相同的模板,因此我可以捕获第二个结果集,即第二个&#34; From&#34;第二个&#34; To&#34;。我相信有一个position()
函数可以使用,但我不确定如何。
答案 0 :(得分:1)
试试这个:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl"
>
<xsl:output method="html" encoding="UTF-8" indent="yes" />
<xsl:template match="TerminalRoutes">
<tr>
<td>
<b>Terminal Routes</b>
</td>
<td> </td>
<td> </td>
</tr>
<xsl:apply-templates select=".//*" />
</xsl:template>
<xsl:template match="/TerminalRoutes/Segment/From">
<tr>
<td>TERMINAL ROUTES FROM</td>
<td>
<xsl:value-of select="./previous"></xsl:value-of>
</td>
<td>
<xsl:value-of select="./current"></xsl:value-of>
</td>
</tr>
<tr>
<td>TERMINAL ROUTES TO</td>
<td>
<xsl:value-of select="../../Segment/To[1 + count(preceding-sibling::*)]/previous"></xsl:value-of>
</td>
<td>
<xsl:value-of select="../../Segment/To[1 + count(preceding-sibling::*)]/current"></xsl:value-of>
</td>
</tr>
</xsl:template>
<xsl:template match="*" />
</xsl:stylesheet>
1 + count(preceding-sibling::*)
通过计算其前面的数字(NB:索引从1开始,而不是XML技术中的0),为您提供当前FROM元素与其兄弟节点相比的索引。
然后,我们使用此数字来指定我们希望To
元素与我们当前匹配的From
元素具有相同的索引。
注意:尽管上述解决方案有效,但如果可能,我建议采用更好的方法:重构源XML以更好地分组数据;即将相关的FROM和TO值放在同一个父级下,这样数据结构就意味着这种关系,使得阅读,验证和使用起来更加简单。
e.g。
<TerminalRoutes>
<Route>
<From>
<previous>DEN </previous>
<current>DNV</current>
</From>
<To>
<previous>ATL </previous>
<current>ATN</current>
</To>
</Route>
<Route>
<From>
<previous>LAX </previous>
<current>LAS</current>
</From>
<To>
<previous>JFK</previous>
<current>LGA </current>
</To>
</Route>
</TerminalRoutes>
答案 1 :(得分:0)
就像position()
循环中for-each
的使用方式一样:
<?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" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="TerminalRoutes">
<table>
<xsl:for-each select="Segment/From">
<xsl:variable name="position" select="position()"/>
<tr>
<td>
<b>Terminal Routes</b>
</td>
<td> </td>
<td> </td>
</tr>
<tr>
<td>TERMINAL ROUTES FROM</td>
<td>
<xsl:value-of select="previous"></xsl:value-of>
</td>
<td>
<xsl:value-of select="current"></xsl:value-of>
</td>
</tr>
<tr>
<td>TERMINAL ROUTES TO</td>
<td>
<xsl:value-of select="//Segment/To[$position]/previous"></xsl:value-of>
</td>
<td>
<xsl:value-of select="//Segment/To[$position]/current"></xsl:value-of>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
输出:
<table>
<tr>
<td><b>Terminal Routes</b></td>
<td> </td>
<td> </td>
</tr>
<tr>
<td>TERMINAL ROUTES FROM</td>
<td>DEN </td>
<td>DNV</td>
</tr>
<tr>
<td>TERMINAL ROUTES TO</td>
<td>ATL </td>
<td>ATN</td>
</tr>
<tr>
<td><b>Terminal Routes</b></td>
<td> </td>
<td> </td>
</tr>
<tr>
<td>TERMINAL ROUTES FROM</td>
<td>LAX </td>
<td>LAS</td>
</tr>
<tr>
<td>TERMINAL ROUTES TO</td>
<td>JFK</td>
<td>LGA </td>
</tr>
</table>
position()
会自动在for-each循环中递增,因此第一个select="//Segment/To[$position]/previous"
//Segment/To[1]/previous
为Segment/From
,第二个//Segment/To[2]/previous
为{{1}}。<登记/>
供参考:http://msdn.microsoft.com/en-US/en-en/library/ms256233%28v=vs.110%29.aspx