这是一个基于标识模板的 XSLT 1.0 解决方案,对<Link>
元素进行了特殊处理。
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="Link">
<xsl:if test="not(preceding-sibling::node()[1][self::Link])">
<xsl:variable name="link">
<xsl:copy-of select="
text()
|
following-sibling::Link[
preceding-sibling::node()[1][self::Link]
and
generate-id(current())
=
generate-id(
preceding-sibling::Link[
not(preceding-sibling::node()[1][self::Link])
][1]
)
]/text()
" />
</xsl:variable>
<xsl:choose>
<xsl:when test="contains($link, '://')">
<ext-link ext-link-type="uri" xlink:href="{$link}" />
</xsl:when>
<xsl:when test="contains($link, '@')">
<email>
<xsl:value-of select="$link" />
</email>
</xsl:when>
<xsl:otherwise>
<link type="unknown">
<xsl:value-of select="$link" />
</link>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
我知道所使用的 XPath 表达式是一些相当多毛的怪物,但是在 XPath 1.0 中选择相邻的兄弟并不容易(如果有人对如何在 XPath 1.0 中做到这一点有更好的想法,请继续告诉我)。
不是(前兄弟::节点()[1] [自我::链接])
表示“前一个节点不能是<Link>
”,例如:只有<Link>
“连续第一个”的元素。
以下兄弟姐妹::链接[
前兄弟::node()[1][self::Link]
和
生成 ID(当前())
=
生成ID(
前兄弟姐妹::链接[
不是(前兄弟::节点()[1] [自我::链接])
][1]
)
]
方法
- 从所有以下兄弟姐妹
<Link>
中,选择那些
- 紧跟在 a 之后
<Link>
(例如,它们不是“连续第一个”),并且
current()
节点的 ID (始终<Link>
是“连续第一个”)必须等于:
- 最接近的前面
<Link>
本身是“连续第一个”
如果这是有道理的。
应用于您的输入,我得到:
<p>Here is some random text with an email address
<email>example@example.com</email> and here
is more random text with a url
<ext-link ext-link-type="uri" xlink:href="http://www.example.com" /> near the end of the sentence.</p>