我有这个表(用CSS div {display:table;}完成)
<div class="wl">
<div><div><p>text 1</p></div><div><p>text a</p></div></div>
<div><div><p>text 2</p></div><div><p>text b</p></div></div>
<div><div><p>text 3</p></div><div><p>text c</p></div></div>
<div class="indent"><div><p>text 4</p></div><div><p>text d</p></div></div>
<div><div><p>text 5</p></div><div><p>text e</p></div></div>
</div>
基于class =“indent”行紧跟前一行的事实,我希望这两行合并(和tabled)如下:
<table>
<tr><td><p>text 1</p></td><td><p>text a</p></td></tr>
<tr><td><p>text 2</p></td><td><p>text b</p></td></tr>
<tr><td><p>text 3</p><p>text 4</p></td><td><p>text b</p><p>text d</p></td></tr>
<tr><td><p>text 5</p></td><td><p>text e</p></td></tr>
</table>
试验让我走到这一步,这显然还不起作用:
<xsl:template match="div[contains(@class, 'wl')]">
<table>
<xsl:copy-of select="@*"/>
<xsl:for-each-group select="node()" group-adjacent="boolean(self::following-sibling/@class='indent1')" >
<tr>
<xsl:copy-of select="@*"/>
<xsl:for-each select="div">
<td>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</td>
</xsl:for-each>
</tr>
</xsl:for-each-group>
</table>
</xsl:template>
它给了我第一行。我觉得这不能用分组来完成,因为不能用一些键来识别组,只能通过以下元素的类名来识别。 任何建议都会受到欢迎。
答案 0 :(得分:2)
第一眼明显错误:将self::following-sibling
更改为following-sibling::div
。您想要下一个<div>
兄弟,而不是“此节点,如果它是<following-sibling>
”
答案 1 :(得分:1)
当我处理div
转换为td
元素时,我只需将节点推送到正确的模板中:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="no"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div[contains(@class, 'wl')]">
<table>
<xsl:apply-templates select="@* , node()"/>
</table>
</xsl:template>
<xsl:template match="div[contains(@class, 'wl')]/div">
<tr>
<xsl:apply-templates/>
</tr>
</xsl:template>
<xsl:template match="div[contains(@class, 'wl')]/div[@class = 'indent']" priority="5"/>
<xsl:template match="div[contains(@class, 'wl')]/div/div">
<td>
<xsl:apply-templates/>
</td>
</xsl:template>
<xsl:template match="div[contains(@class, 'wl')]/div[following-sibling::*[1][self::div[@class = 'indent']]]/div" priority="5">
<xsl:variable name="pos"><xsl:number/></xsl:variable>
<td>
<xsl:apply-templates select="node() , ../following-sibling::*[1][self::div[@class = 'indent']]/div[position() = $pos]/node()"/>
</td>
</xsl:template>
</xsl:stylesheet>
正如托比亚斯在评论中正确指出的那样,可以删除一个模板并简单地推送任何后续兄弟的东西:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="no"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div[contains(@class, 'wl')]">
<table>
<xsl:apply-templates select="@* , node()"/>
</table>
</xsl:template>
<xsl:template match="div[contains(@class, 'wl')]/div">
<tr>
<xsl:apply-templates/>
</tr>
</xsl:template>
<xsl:template match="div[contains(@class, 'wl')]/div[@class = 'indent']" priority="5"/>
<xsl:template match="div[contains(@class, 'wl')]/div/div">
<xsl:variable name="pos"><xsl:number/></xsl:variable>
<td>
<xsl:apply-templates select="node() , ../following-sibling::*[1][self::div[@class = 'indent']]/div[position() = $pos]/node()"/>
</td>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:1)
我认为这可以通过分组来完成,就像您当前正在尝试的那样,但 xsl:for-each-group 可能需要看起来像这样:
<xsl:for-each-group select="div" group-starting-with="div[not(@class='indent')]">
然后,要获取构成行中每个单元格的元素,您可以用以下内容替换当前的 xsl:apply-templates :
<xsl:variable name="pos" select="position()" />
<xsl:apply-templates select="current-group()/div[position()=$pos]/*" />
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div[contains(@class, 'wl')]">
<table>
<xsl:copy-of select="@*"/>
<xsl:for-each-group select="div" group-starting-with="div[not(@class='indent')]">
<tr>
<xsl:copy-of select="@*"/>
<xsl:for-each select="div">
<td>
<xsl:copy-of select="@*"/>
<xsl:variable name="pos" select="position()" />
<xsl:apply-templates select="current-group()/div[position()=$pos]/*" />
</td>
</xsl:for-each>
</tr>
</xsl:for-each-group>
</table>
</xsl:template>
</xsl:stylesheet>
答案 3 :(得分:0)
感谢您的精力。 我是XSLT的新手,因为你现在必须知道,并且像疯了一样阅读XSLT。 你的意见是教育。 在您的帮助下,我找到了这个解决方案:
<xsl:template match="div[contains(@class, 'wl')]">
<table>
<xsl:for-each-group select="node()" group-starting-with="node()[not(contains(@class , 'indent'))]" >
<tr>
<td>
<xsl:for-each select="current-group()">
<p><xsl:value-of select="node()[1]"/></p>
</xsl:for-each>
</td>
<td>
<xsl:for-each select="current-group()">
<p><xsl:value-of select="node()[2]"/></p>
</xsl:for-each>
</td>
</tr>
</xsl:for-each-group>
</table>
</xsl:template>