Utilizzando il raggruppamento di mettere insieme testo e poi testarlo
-
25-09-2019 - |
Domanda
Quindi, in questo brutta estruso composizione del prodotto, a volte vedo link e indirizzi e-mail che sono stati suddivisi a parte. Esempio:
<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>
output desiderato:
<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>
spazi bianchi tra gli elementi non sembra verificarsi, che è una benedizione.
Vi posso dire che ho bisogno di usare un xsl: for-each-gruppo all'interno del modello p, ma non riesco proprio a capire come mettere il testo combinato dal gruppo attraverso la contiene () la funzione in modo da distinguere le email da URL. Aiuto?
Soluzione
Se si utilizza gruppo adiacente allora si può semplicemente stringa unirsi al corrente-group () come in
<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>
Altri suggerimenti
Ecco un XSLT 1.0 soluzione basata sul modello di identità, con un trattamento speciale per gli elementi <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>
So che le espressioni XPath utilizzate sono alcuni un mostro abbastanza pelose, ma selezionando i fratelli adiacenti non è facile in XPath 1.0 (se qualcuno ha una migliore idea di come farlo in XPath 1.0, andare avanti e mi dicono).
not(preceding-sibling::node()[1][self::Link])
significa "nodo immediatamente precedente non deve essere un <Link>
", es .: elementi solo <Link>
che sono "prima fila".
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] ) ]
mezzi
- da tutti i seguenti-sibling
<Link>
s, scegliere quelli che- segue immediatamente un
<Link>
(ad esempio non sono "prima fila"), e - l'ID del nodo
current()
(sempre un<Link>
che è "prima fila") deve essere uguale a: - il
<Link>
precedente più prossima che si è "prima fila"
- segue immediatamente un
Se questo ha un senso.
Applicata al vostro ingresso, ottengo:
<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>