Использование группировки, чтобы собрать текст и затем проверить его
Так что в этом чудовищном экструдированном наборе текста я иногда вижу ссылки и адреса электронной почты, которые были разделены. Пример:
<p>Here is some random text with an email address
<Link>example</Link><Link>@example.com</Link> and here
is more random text with a url
<Link>http://www.</Link><Link>example.com</Link> near the end of the sentence.</p>
Желаемый результат:
<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/">
http://www.example.com/</ext-link> near the end of the sentence.</p>
Пробелы между элементами не появляются, что является одним из благословений.
Я могу сказать, что мне нужно использовать xsl:for-each-group в шаблоне p, но я не совсем понимаю, как поместить объединенный текст из группы с помощью функции contains(), чтобы отличать электронные письма от URL-адресов. Помогите?
2 ответа
Если вы используете группу-смежную, то вы можете просто присоединить строку к текущей группе (), как в
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xsd"
version="2.0">
<xsl:template match="p">
<xsl:copy>
<xsl:for-each-group select="node()" group-adjacent="boolean(self::Link)">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<xsl:variable name="link-text" as="xsd:string" select="string-join(current-group(), '')"/>
<xsl:choose>
<xsl:when test="matches($link-text, '^https?://')">
<ext-link ext-link-type="uri" xlink:href="{$link-text}">
<xsl:value-of select="$link-text"/>
</ext-link>
</xsl:when>
<xsl:otherwise>
<email><xsl:value-of select="$link-text"/></email>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Вот решение 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>
элементы, которые являются "первыми в ряду".
follow-sibling:: Link [previous-sibling:: node ()[1][self:: Link] и генерировать-id (current ()) = генерировать-id (previous-sibling:: Link [не (previous-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>