Вот решение 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, продолжайте и скажите мне). *
not(preceding-sibling::node()[1][self::Link])
означает, что «непосредственно предшествующий узел не должен быть <Link>
», например, только <Link>
элементов, которые «первыми в ряду».
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]
)
]
означает
- из всех следующих братьев и сестер
<Link>
s, выберите те, которые
- сразу же следует за
<Link>
(например, они не "первыми в ряду") и
- идентификатор узла
current()
(всегда <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>