我希望基于一个值将特定的XML节点组合在一起,并以每行两个元素的最大值显示输出。
我试了很多次,但找不到一个可行的逻辑。
首先,这里有一个XML示例:
<apples>
<gala>
<pattern></pattern>
<mutated>self</mutated>
<marketed>Gala</marketed>
</gala>
<gala>
<pattern>stripe</pattern>
<mutated>Gala</mutated>
<marketed>Royal Gala</marketed>
</gala>
<gala>
<pattern>stripe</pattern>
<mutated>Tenroy</mutated>
<marketed>Obrogala</marketed>
</gala>
<gala>
<pattern>stripe</pattern>
<mutated>Tenroy</mutated>
<marketed>Waliser Gala</marketed>
</gala>
<gala>
<pattern>stripe</pattern>
<mutated>Tenroy</mutated>
<marketed>Caitlin</marketed>
</gala>
<gala>
<pattern>stripe</pattern>
<mutated>Imperial</mutated>
<marketed>Banning Gala</marketed>
</gala>
<gala>
<pattern>stripe</pattern>
<mutated>Tenroy</mutated>
<marketed>Smith gala</marketed>
</gala>
</apples>我想把苹果按突变分类,但前提是它们有规律。产出应如下:
Mutated from: Gala
Marketed as Royal Gala
Mutated from Tenroy
Marketed as Obrogala :: Marketed as Waliser Gala
Marketed as Caitlin :: Marketed as Smith Gala
Mutated from Imperial
Marketed as Banning Gala另外,一个更简单的解决方案不是在"Tenroy“组中添加”作为Smith Gala的营销“,而是在”帝国“组下创建一个新的组"Tenroy”。
以下是我到目前为止尝试过的:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="apples">
<html>
<body>
<h2>Gala Apples</h2>
<xsl:for-each select="gala[normalize-space(pattern)][position() mod 2=1]">
<!-- Add a headline for each mutation -->
<xsl:if test="preceding-sibling::gala[normalize-space(pattern)][1]/mutated != mutated or position() = 1">
<table border="1">
<tr bgcolor="#9acd32">
<th>
Mutated from: <xsl:value-of select="mutated" />
</th>
</tr>
</table>
</xsl:if>
<!-- Build a 2 column Layout for each Gala Apple -->
<table border="1">
<tr>
<td width="50%">
Marketd as: <xsl:value-of select="marketed" />
</td>
<td width="50%">
<xsl:for-each select="following-sibling::gala[normalize-space(pattern)][1]">
Marketd as: <xsl:value-of select="marketed" />
</xsl:for-each>
</td>
</tr>
</table>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>我的代码的问题是,在检查突变时,我只遍历第一个节点(mod 2=1)。如果每个小组都有偶数的苹果,这会很好。如果没有,它最终将陷入一片混乱。
我也试着数一数之前的兄弟姐妹突变的数量,但它也没有达到预期的效果。
如果能提供帮助,我们将不胜感激!
发布于 2014-01-10 08:19:02
如果您的处理器支持它,您可以使用EXSLT set:distinct()函数按突变对记录进行分组,例如:
<xsl:variable name="groups" select="set:distinct(/apples/gala/mutated)[.!='self']" />而不是使用(更复杂的) Muenchian方法。然后,您可以使用键来获取每个组中的苹果并对其进行处理。IMHO,组应该以列表的形式输出,两列显示由CSS处理,但是如果您更愿意通过表格单元格来处理它,请尝试如下所示:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:set="http://exslt.org/sets">
<xsl:variable name="groups" select="set:distinct(/apples/gala/mutated)[.!='self']" />
<xsl:key name="samegGroup" match="gala" use="mutated" />
<xsl:template match="/">
<html>
<body>
<h2>Gala Apples</h2>
<table border="1" >
<xsl:for-each select="$groups">
<tr><th colspan="2"><xsl:value-of select="." /></th></tr>
<xsl:call-template name="proc">
<xsl:with-param name="group" select="key('samegGroup', .)"/>
</xsl:call-template>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
<xsl:template name="proc">
<xsl:param name="group" />
<xsl:param name="i" select="1"/>
<xsl:choose>
<xsl:when test="$i > count($group)"/>
<xsl:otherwise>
<tr>
<td>
<xsl:text>Marketed as: </xsl:text>
<xsl:value-of select="$group[$i]/marketed" />
</td>
<td>
<xsl:if test="$i < count($group)">
<xsl:text>Marketed as: </xsl:text>
<xsl:value-of select="$group[$i+1]/marketed" />
</xsl:if>
</td>
</tr>
<xsl:call-template name="proc">
<xsl:with-param name="group" select="$group"/>
<xsl:with-param name="i" select="$i+2"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>https://stackoverflow.com/questions/21036213
复制相似问题