我正在尝试向 XML 文档中存储的 HTML 格式文本中的关键字添加超链接。
XML 片段:
<NoteText>Heading of note<br/>
Body of note blah blah keyword blah blah.<br/>
May contain more lines.</NoteText>
所需输出:
Heading of note<br/>
Body of note blah blah <a href="http://127.0.0.1/">keyword</a> blah blah.<br/>
May contain more lines.
XSLT 模板的原始尝试。这会添加 HTML 标签,但会丢失所有现有格式。
<xsl:template name="string-replace-all">
<xsl:param name="text" />
<xsl:param name="replace" />
<xsl:param name="by" />
<xsl:choose>
<xsl:when test="contains($text, $replace)">
<xsl:value-of select="substring-before($text,$replace)" disable-output-escaping="yes" />
<xsl:value-of select="$by" disable-output-escaping="yes" />
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="substring-after($text,$replace)" />
<xsl:with-param name="replace" select="$replace" />
<xsl:with-param name="by" select="$by" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text" disable-output-escaping="yes" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
第二次尝试。这会保留现有格式,但添加新的 HTML 作为显示文本而不是功能标记。
<xsl:template name="string-replace-formatted">
<xsl:param name="text" />
<xsl:param name="replace" />
<xsl:param name="by" />
<xsl:choose>
<xsl:when test="contains($text, $replace)">
<xsl:copy-of select="substring-before($text,$replace)" />
<xsl:copy-of select="$by" />
<xsl:call-template name="string-replace-formatted">
<xsl:with-param name="text" select="substring-after($text,$replace)" />
<xsl:with-param name="replace" select="$replace" />
<xsl:with-param name="by" select="$by" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$text" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
所以,我正在寻找两全其美的方法 - 如何保留现有的 HTML 标签并添加新的 HTML 标签?是否可以使用像我这里这样的通用模板(以便它可以重用于其他标签),或者我是否需要一个单一用途的模板,该模板具有找到和替换的字符串的常量值?
使用 xslt 1.0 你可以尝试这样的事情:
<?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>
<xsl:template match="NoteText//text()">
<xsl:call-template name="make-link">
<xsl:with-param name="linktext" select="'keyword'"/>
<xsl:with-param name="link" >
<a href="http://127.0.0.1/"/>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template name="make-link">
<xsl:param name="text" select="." />
<xsl:param name="linktext" />
<xsl:param name="link" />
<xsl:choose>
<xsl:when test="contains($text, $linktext)">
<xsl:copy-of select="substring-before($text,$linktext)" />
<a href="http://127.0.0.1/">
<xsl:value-of select="$linktext" />
</a>
<xsl:call-template name="make-link">
<xsl:with-param name="text" select="substring-after($text,$linktext)" />
<xsl:with-param name="linktext" select="$linktext" />
<xsl:with-param name="link" select="$link" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
这对于 XSLT 3 来说是一项简单的工作:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:template match="NoteText//text()">
<xsl:apply-templates select="analyze-string(., 'keyword')" mode="wrap-match"/>
</xsl:template>
<xsl:template match="fn:match" mode="wrap-match">
<a href="http://localhost/">{.}</a>
</xsl:template>
<xsl:mode on-no-match="shallow-copy"/>
</xsl:stylesheet>
XSLT 3 可用于 Java 平台的 Saxon、.NET 平台、用于 Python/C/C++ 的 SaxonC、用于 Node.js 和浏览器的 SaxonJS。