XSLT分组表行
我有这个表(用CSS div{display:table;}完成)XSLT分组表行,xslt,Xslt,我有这个表(用CSS div{display:table;}完成) 正文1正文a 文本2文本b 文本3文本c 文本4文本d 文本5文本e 基于class=“indent”行紧跟在前一行之后的事实,我希望这两行合并(并以表格形式显示),如下所示: <table> <tr><td><p>text 1</p></td><td><p>text a</p></td>
正文1正文a
文本2文本b
文本3文本c
文本4文本d
文本5文本e
基于class=“indent”行紧跟在前一行之后的事实,我希望这两行合并(并以表格形式显示),如下所示:
<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>
正文1正文a
文本2文本b
正文3正文4正文b正文d
文本5文本e
实验让我走了这么远,但显然还不起作用:
<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>
它只给我第一排。我觉得这不能用分组来完成,因为不能用某个键来标识组,只能通过下面元素的类名来标识。
欢迎任何建议。第一眼看到的明显错误:将
self::following sibling
更改为following sibling::div
。您想要的是下一个
同级节点,而不是“如果它是
,则此节点”第一眼看到的明显错误:将self::following sibling
更改为following sibling::div
。您想要的是下一个
同级节点,而不是“如果它是
,则此节点”当我处理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>
正如Tobias在一篇评论中正确指出的那样,可以消除一个模板,并简单地推送任何以下同级内容(如果存在):
<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>
当我处理
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>
正如Tobias在一篇评论中正确指出的那样,可以消除一个模板,并简单地推送任何以下同级内容(如果存在):
<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>
谢谢你的精力。
我是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>
谢谢你的精力。
我是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>
我认为这可以通过分组来实现,按照您当前尝试的方式,但是您的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>
我认为这可以通过分组来实现,按照您当前尝试的方式,但是您的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>
您不需要最后一个模板,只需将其内容放入
中即可。如果没有直接跟随的带有缩进的div,它无论如何都不会应用。@TobiasKlevenz,你是对的,我已经编辑并提供了实现该更改的第二个示例。你不需要最后一个模板,只需将其内容放在
中即可。如果没有直接跟随的带有缩进的div,它无论如何都不会应用。@TobiasKlevenz,你是对的,我已经编辑并提供了实现该更改的第二个示例。你的示例输出有两次“文本b”,而完全没有“文本c”。第二个“文本b”应该是“文本c”吗?是的。很抱歉,您的示例输出有两次“文本b”,而“文本c”根本没有。第二个“文本b”应该是“文本c”吗?是的。很抱歉输入了+1。不仅如此,您只需要下一个
同级元素(单数),而不是下面的所有同级::div元素。所以,下面的兄弟::div[1]
+1。不仅如此,您只需要下一个
同级元素(单数),而不是下面的所有同级::div元素。所以,下面的兄弟::div[1]
。很好。柜台有点难看,但我看不到消除它的方法。下一件事是给文本4和文本d都class='indent'。但也许在CSS中做得更好(而不是(第一个孩子))。很好。柜台有点难看,但我看不到消除它的方法。下一件事是给文本4和文本d都class='indent'。但也许在CSS中做得更好(而不是(第一个孩子))。