我有一个包含多个<b>
元素的输入xml文件,我必须包装连续出现的所有<b>
。我为此写了一个xsl。这是更好的方法吗?在包装元素之后,在转换期间还会产生额外的空间。
示例输入XML
<chap>
<p><b>The</b> <b>Attorney</b> General <b>(Fees)</b><b>a</b><b>b</b><b>c</b> Determination 2012 No 110 commenced on 1 <b>July</b> <b>2012</b> <b>and</b> was repealed on <b>1</b> <b>July</b> <b>2013</b>. The Determination is yet to be amended by:</p>
</chap>
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:guru="Self"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="b[preceding-sibling::node()[1][self::b]]
|b[preceding-sibling::node()[1][normalize-space(.) = '']][preceding-sibling::node()[2][self::b]]"/>
<xsl:template match="b">
<xsl:copy>
<xsl:apply-templates/>
<xsl:if test="following-sibling::node()[1][self::b]">
<xsl:copy-of select="guru:wrap(following-sibling::node()[1], '')"/>
</xsl:if>
<xsl:if test="following-sibling::node()[1][normalize-space(.) = '']/following-sibling::node()[1][self::b]">
<xsl:copy-of select="guru:wrap(following-sibling::node()[2], following-sibling::node()[1])"/>
</xsl:if>
</xsl:copy>
</xsl:template>
<xsl:function name="guru:wrap">
<xsl:param name="b_data"/>
<xsl:param name="space"/>
<xsl:value-of select="$space"/>
<xsl:value-of select="$b_data"/>
<xsl:if test="$b_data/following-sibling::node()[1][self::b]">
<xsl:copy-of select="guru:wrap($b_data/following-sibling::node()[1], '')"/>
</xsl:if>
<xsl:if test="$b_data/following-sibling::node()[1][normalize-space(.) = '']/following-sibling::node()[1][self::b]">
<xsl:copy-of select="guru:wrap($b_data/following-sibling::node()[2], $b_data/following-sibling::node()[1])"/>
</xsl:if>
</xsl:function>
</xsl:stylesheet>
输出
<chap>
<p><b>The Attorney</b> General <b>(Fees)abc</b> Determination 2012 No 110 commenced on 1 <b>July 2012 and</b> was repealed on <b>1 July 2013</b> . The Determination is yet to be amended by:</p>
</chap>
所需输出
<chap>
<p><b>The Attorney</b> General <b>(Fees)abc</b> Determination 2012 No 110 commenced on 1 <b>July 2012 and</b> was repealed on <b>1 July 2013</b>. The Determination is yet to be amended by:</p>
</chap>
先谢谢。
答案 0 :(得分:1)
我建议使用for-each-group group-adjacent="self::b or self::text()[. = ' ']"
:
<xsl:template match="p">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:for-each-group select="node()" group-adjacent="self::b or self::text()[. = ' ']">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<b>
<xsl:apply-templates select="current-group()/node() | current-group()[self::text()]"/>
</b>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
https://xsltfiddle.liberty-development.net/gWmuiHU/1显示结果,它使用XSLT 3,但对于XSLT 2,您只需删除xsl:mode
并保留身份模板
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
你的代码中有。