我正在尝试编写一个XSLT,根据标题级别将
HTML文件组织到不同的部分级别.这是我的意见:
<html> <head> <title></title> </head> <body> <h1>HEADER 1 CONTENT</h1> <p>Level 1 para</p> <p>Level 1 para</p> <p>Level 1 para</p> <p>Level 1 para</p> <h2>Header 2 CONTENT</h2> <p>Level 2 para</p> <p>Level 2 para</p> <p>Level 2 para</p> <p>Level 2 para</p> </body> </html>
我目前正在使用一个相当简单的结构,所以这种模式将暂时保持不变.我需要这样的输出……
<document> <section level="1"> <header1>Header 1 CONTENT</header1> <p>Level 1 para</p> <p>Level 1 para</p> <p>Level 1 para</p> <p>Level 1 para</p> <section level="2"> <header2>Header 2 CONTENT</header2> <p>Level 2 para</p> <p>Level 2 para</p> <p>Level 2 para</p> <p>Level 2 para</p> </section> </section> </document>
我一直在使用这个例子:Stackoverflow Answer
但是,我无法让它完全按照我的需要去做.
我正在使用Saxon 9在Oxygen中运行xslt for dev.我将在生产中使用cmd / bat文件.仍然撒克逊9.如果可能的话,我想处理多达4个嵌套的部分级别.
任何帮助深表感谢!
因为我遇到了另一个规定,所以我需要补充一下.我以前可能应该想到这个.
我遇到以下代码示例
<html> <head> <title></title> </head> <body> <p>Level 1 para</p> <p>Level 1 para</p> <p>Level 1 para</p> <p>Level 1 para</p> <h1>Header 2 CONTENT</h1> <p>Level 2 para</p> <p>Level 2 para</p> <p>Level 2 para</p> <p>Level 2 para</p> </body> </html>
如您所见,< p>是< body>的孩子在我的第一个片段中,< p>始终是标题级别的孩子.我想要的结果与上面相同,只是当我遇到< p>时作为< body>的子项,它应该包含在< section level =“1”>中.
<document> <section level="1"> <p>Level 1 para</p> <p>Level 1 para</p> <p>Level 1 para</p> <p>Level 1 para</p> </section> <section level="1"> <header1>Header 2 CONTENT</header1> <p>Level 2 para</p> <p>Level 2 para</p> <p>Level 2 para</p> <p>Level 2 para</p> </section> </document>
解决方法
这是一个XSLT 2.0样式表:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mf="http://example.com/mf" exclude-result-prefixes="xs mf" version="2.0"> <xsl:output indent="yes"/> <xsl:function name="mf:group" as="node()*"> <xsl:param name="elements" as="element()*"/> <xsl:param name="level" as="xs:integer"/> <xsl:for-each-group select="$elements" group-starting-with="*[local-name() eq concat('h',$level)]"> <xsl:choose> <xsl:when test="self::*[local-name() eq concat('h',$level)]"> <section level="{$level}"> <xsl:element name="header{$level}"><xsl:apply-templates/></xsl:element> <xsl:sequence select="mf:group(current-group() except .,$level + 1)"/> </section> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="current-group()"/> </xsl:otherwise> </xsl:choose> </xsl:for-each-group> </xsl:function> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@*,node()"/> </xsl:copy> </xsl:template> <xsl:template match="/html"> <document> <xsl:apply-templates select="body"/> </document> </xsl:template> <xsl:template match="body"> <xsl:sequence select="mf:group(*,1)"/> </xsl:template> </xsl:stylesheet>
它应该按照你的要求做,尽管它不会停留在四个嵌套级别,而是只要找到h [n]个元素就可以停止.