首先,我们将从一个标识模板开始:
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@*, node()"/>
</xsl:copy>
</xsl:template>
其次,我们必须匹配根节点
w:body
并使用
xsl:for-each-group
。之后,我们将节点存储在变量(firstpass)中,以便稍后进一步操作节点,例如:
<!-- If you want to specify the target node (1 in 22 as you say),
you can adjust the xpath below to match your target node.
-->
<xsl:template match="w:body">
<xsl:variable name="firstPass">
<xsl:for-each-group select="*" group-adjacent="boolean(self::w:p[descendant::w:ilvl])">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<!-- the zero (0) was obtained from the value of
w:val attribute of w:ilvl node -->
<xsl:sequence select="mf:group(current-group(), 0)"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:variable>
<xsl:apply-templates select="$firstPass/node()"/>
</xsl:template>
我们可以调整你提到的功能。我们可以将组相邻的目标节点修改为
<xsl:function name="mf:group" as="node()*">
<xsl:param name="nodes" as="node()*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:if test="$nodes">
<ul>
<xsl:for-each-group select="$nodes"
group-adjacent="boolean(self::*[descendant::w:ilvl/@w:val = $level])">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<xsl:apply-templates select="current-group()"/>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="mf:group(current-group(), $level + 1)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</ul>
</xsl:if>
</xsl:function>
以下是清理所需的模板
<xsl:template match="w:p">
<xsl:apply-templates select="descendant::w:t"/>
</xsl:template>
<xsl:template match="w:p[.='']|w:sectPr"/>
<xsl:template match="w:t">
<xsl:choose>
<xsl:when test="ancestor::w:p[descendant::w:pStyle[@w:val='ListParagraph']]">
<li>
<xsl:apply-templates/>
</li>
</xsl:when>
<xsl:otherwise>
<p>
<xsl:apply-templates/>
</p>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
之后,我们仍然需要插入
<ul>
子级到父级
<li>
.要做到这一点,我们必须进行第二次转变。
现在,我们将匹配firstpass变量中存在的节点
<xsl:template match="li[following-sibling::*[1][name()='ul']]">
<xsl:copy>
<xsl:apply-templates/>
<!-- this will copy the target ul nodes, albeit in a different mode -->
<xsl:apply-templates select="following-sibling::*[1][name()='ul']" mode="transfer"/>
</xsl:copy>
</xsl:template>
<!-- this will delete the target node -->
<xsl:template match="ul[preceding-sibling::*[1][name()='li']]"/>
以及其他模式的标识模板
<xsl:template match="@* | node()" mode="transfer">
<xsl:copy>
<xsl:apply-templates select="@*, node()"/>
</xsl:copy>
</xsl:template>
整个样式表如下所示:
<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"
xmlns:w="www.wnamespace.com"
version="2.0"
exclude-result-prefixes="xs mf w">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:function name="mf:group" as="node()*">
<xsl:param name="nodes" as="node()*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:if test="$nodes">
<ul>
<xsl:for-each-group select="$nodes"
group-adjacent="boolean(self::*[descendant::w:ilvl/@w:val = $level])">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<xsl:apply-templates select="current-group()"/>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="mf:group(current-group(), $level + 1)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</ul>
</xsl:if>
</xsl:function>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@*, node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@* | node()" mode="transfer">
<xsl:copy>
<xsl:apply-templates select="@*, node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="w:p">
<xsl:apply-templates select="descendant::w:t"/>
</xsl:template>
<xsl:template match="w:p[.='']|w:sectPr"/>
<xsl:template match="w:t">
<xsl:choose>
<xsl:when test="ancestor::w:p[descendant::w:pStyle[@w:val='ListParagraph']]">
<li>
<xsl:apply-templates/>
</li>
</xsl:when>
<xsl:otherwise>
<p>
<xsl:apply-templates/>
</p>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="w:body">
<xsl:variable name="firstPass">
<xsl:for-each-group select="*" group-adjacent="boolean(self::w:p[descendant::w:ilvl])">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<xsl:sequence select="mf:group(current-group(), 0)"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:variable>
<xsl:apply-templates select="$firstPass/node()"/>
</xsl:template>
<xsl:template match="ul[preceding-sibling::*[1][name()='li']]"/>
</xsl:stylesheet>
在行动中看到它
here
。