新手求助:基于指定条件的XSLT元素序列分组XML转换
XSLT分组转换XML解决方案
输入XML
<p style="Chap"></p> <p style="ChapTitle"></p> <p style="IntroHead">IntroHead</p> <p style="IntroText">IntroText</p> <p style="IntroText">IntroText</p> <p style="IntroText">IntroText</p> <p style="IntroLast">IntroLast</p> <p style="Normal"></p> <p style="Bullet">Bullet</p> <p style="Bullet">Bullet</p> <p style="Bullet">Bullet</p> <p style="Bullet">Bullet</p> <p style="Bullet">Bullet</p> <p style="BulletLast">BulletLast</p> <p style="Normal"></p> <p style="Normal"></p> <p style="Normal"></p> <p style="Normal"></p> <p style="Normal"></p> <p style="Normal"></p> <p style="Normal"></p> <p style="Normal"></p>
期望输出XML
<p style="Chap"></p> <p style="ChapTitle"></p> <box> <title>IntroHead</title> <list> <li>IntroText</li> <li>IntroText</li> <li>IntroText</li> <li>IntroLast</li> </list> </box> <p style="Normal"></p> <list style="bullet"> <li>Bullet</li> <li>Bullet</li> <li>Bullet</li> <li>Bullet</li> <li>Bullet</li> <li>BulletLast</li> </list> <p style="Normal"></p> <p style="Normal"></p> <p style="Normal"></p> <p style="Normal"></p> <p style="Normal"></p> <p style="Normal"></p> <p style="Normal"></p> <p style="Normal"></p>
XSLT实现代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 匹配根节点并遍历所有子节点 --> <xsl:template match="/"> <xsl:for-each-group select="node()" group-adjacent="boolean(self::p[starts-with(@style, 'Intro') or starts-with(@style, 'Bullet')])"> <!-- 直接输出非分组节点 --> <xsl:if test="not(current-grouping-key())"> <xsl:copy-of select="current-group()"/> </xsl:if> <!-- 处理Intro系列分组 --> <xsl:if test="current-grouping-key() and current-group()[1]/@style='IntroHead'"> <box> <title> <xsl:value-of select="current-group()[@style='IntroHead']"/> </title> <list> <xsl:for-each select="current-group()[not(@style='IntroHead')]"> <li> <xsl:value-of select="."/> </li> </xsl:for-each> </list> </box> </xsl:if> <!-- 处理Bullet系列分组 --> <xsl:if test="current-grouping-key() and starts-with(current-group()[1]/@style, 'Bullet')"> <list style="bullet"> <xsl:for-each select="current-group()"> <li> <xsl:value-of select="."/> </li> </xsl:for-each> </list> </xsl:if> </xsl:for-each-group> </xsl:template> </xsl:stylesheet>
关键逻辑说明
- 用
<xsl:for-each-group>的group-adjacent属性,把相邻的Intro/Bullet系列<p>元素归为一组 - 非分组节点(如Chap、ChapTitle、Normal样式的
<p>)直接原样输出 - Intro组:外层套
<box>,将IntroHead内容转为<title>,其余IntroText/IntroLast转为<list>下的<li> - Bullet组:外层套带
style="bullet"的<list>,所有Bullet/BulletLast内容转为<li>
内容的提问来源于stack exchange,提问作者Hari Haran
相关产品推荐
相关产品推荐

