这是一个经过测试的工作实现,包括如何从文本节点的右侧或左侧修剪空白:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<!-- Match if the preceding node (not necessarily sibling) that is either
a non-empty-space-text node or an <lb> is an <lb break='no'> -->
<xsl:template match="text()[
(preceding::node()[
self::text()[normalize-space() != ''] or
self::lb])
[last()]
[self::lb[@break='no']]
]">
<!-- Trim whitespace on the left. Thanks to Alejandro,
http://stackoverflow.com/a/3997107/423105 -->
<xsl:variable name="firstNonSpace"
select="substring(normalize-space(), 1, 1)"/>
<xsl:value-of select="concat($firstNonSpace,
substring-after(., $firstNonSpace))"/>
</xsl:template>
<!-- Match if the next node (not necessarily sibling) that is either
a non-empty-space-text node or an <lb> is an <lb break='no'> -->
<xsl:template match="text()[
following::node()[
self::text()[normalize-space() != ''] or
self::lb]
[1]
[self::lb[@break='no']]
]">
<xsl:variable name="normalized" select="normalize-space()"/>
<xsl:if test="$normalized != ''">
<xsl:variable name="lastNonSpace"
select="substring($normalized, string-length($normalized))"/>
<xsl:variable name="trimmedSuffix">
<xsl:call-template name="substring-after-last">
<xsl:with-param name="string" select="."/>
<xsl:with-param name="delimiter" select="$lastNonSpace"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="substring(., 1, string-length(.) -
string-length($trimmedSuffix))"/>
</xsl:if>
<!-- otherwise output nothing. -->
</xsl:template>
<!-- Thanks to Jeni Tennison:
http://www.stylusstudio.com/xsllist/200111/post00460.html -->
<xsl:template name="substring-after-last">
<xsl:param name="string" />
<xsl:param name="delimiter" />
<xsl:choose>
<xsl:when test="contains($string, $delimiter)">
<xsl:call-template name="substring-after-last">
<xsl:with-param name="string"
select="substring-after($string, $delimiter)" />
<xsl:with-param name="delimiter" select="$delimiter" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise><xsl:value-of select="$string" /></xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
我在这里的假设是,在回答我上面的“下一个歧义”评论之前,如果有一个没有<lb>
的元素,则在它充当忽略空白的边界的意义上构成“周围文本”。 break="no"
<lb>
样本输入:
<test>
<t1>
This <emph>little <ref>tea </ref> </emph>
<lb break="no" />
pot, short and stout.
</t1>
<t2>
This <emph>little <ref>tea </ref> </emph>
<lb />
<lb break="no" />
pot, short and stout.
</t2>
</test>
输出:
<test>
<t1>
This <emph>little <ref>tea</ref></emph><lb break="no"/>pot, short and stout.
</t1>
<t2>
This <emph>little <ref>tea </ref> </emph>
<lb/><lb break="no"/>pot, short and stout.
</t2>
</test>
此输出是正确的 AFAICT。如果没有,请告诉我原因,我会看看如何修复它。