这种转变:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kFollowing" match="/*/node()[not(self::nl)]"
use="generate-id(preceding-sibling::nl[1])"/>
<xsl:key name="kPreceding" match="/*/node()[not(self::nl)]"
use="generate-id(following-sibling::nl[1])"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates select="@*|nl"/>
</xsl:copy>
</xsl:template>
<xsl:template match="nl" name="groupFollowing">
<title>
<xsl:apply-templates select="key('kFollowing',generate-id())"/>
</title>
</xsl:template>
<xsl:template match="nl[1]">
<title>
<xsl:apply-templates select="key('kPreceding',generate-id())"/>
</title>
<xsl:call-template name="groupFollowing"/>
</xsl:template>
</xsl:stylesheet>
应用于提供的 XML 文档时:
<p>
XYZZ
<nl/>
DEF
<process> gggg </process>
KKK
<nl/>
JKLK
<nl/>
QQQQ
</p>
产生想要的正确结果:
<p>
<title>
XYZZ
</title>
<title>
DEF
<process> gggg </process>
KKK
</title>
<title>
JKLK
</title>
<title>
QQQQ
</title>
</p>
请注意:
身份规则用于“按原样”复制节点。
有特定的模板匹配顶部元素、顶部元素的第一nl个子元素和顶部元素的任何子nl元素。
定义了两个键来选择nl紧接在一个元素之前的所有非节点nl和紧随一个元素的所有节点nl。
一个nl元素被一个元素替换title,所有紧随其后的非nl节点都被处理,结果被放入这个title元素。
对于第一个(其父级的子级)nl元素,有一个初始步骤,在该步骤中添加一个title元素,处理所有紧接在其前面的非nl节点,并将结果放入该title元素中。然后执行上述步骤4.中的处理。