使用 XSLT 标记匹配正则表达式的文本?
Use XSLT to mark up text matching regex?
我正在尝试在 HTML 文档上使用 XSLT 2.0 (Saxon-PE 9.6) 来创建围绕来自指定非拉丁 Unicode 块(允许空格)的所有连续字符运行的标签。我需要将此过程应用于文档中的每个 text() 节点。我已经通过使用 <xsl:analyze-string>
和 fn:replace()
的两种方法取得了一些进展,但我无法得出令人满意的完整解决方案。
例如,这里有一些包含印地语的文本:
输入:<p>चाय का कप means ‘cup of tea’ in हिन्दि.</p>
期望输出:<p><span xml:lang="hi-Deva">चाय का कप</span> means ‘cup of tea’ in <span xml:lang="hi-Deva">हिन्दि</span>.</p>
如何在 XSLT 2.0 中实现此过程?
这是我对 <xsl:analyze-string>
的尝试:
(注意:印地语使用天城文代码块 U+0900 到 U+097F。)
<xsl:template match="text()">
<xsl:variable name="textValue" select="."/>
<xsl:analyze-string select="$textValue" regex="(\s*.*?)([ऀ-ॿ]+)((\s+[ऀ-ॿ]+)*)(\s*.*)">
<xsl:matching-substring>
<xsl:value-of select="regex-group(1)"/>
<span xml:lang="hi-Deva"><xsl:value-of select="regex-group(2)"/><xsl:value-of select="regex-group(3)"/></span>
<xsl:value-of select="regex-group(5)"/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="$textValue"/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
在测试输入中,这会产生:
<p><span xml:lang="hi-Deva">चाय का कप</span> means ‘cup of tea’ in हिन्दि.</p>
这种方法遗漏了印地语文本的第二个区域 (हिन्दि)。我需要一种方法来查找并标记所有与正则表达式匹配的事件。
我的第二种方法使用 fn:replace()
:
<xsl:template match="text()">
<xsl:value-of select='fn:replace(., "[ऀ-ॿ]+(\s+[ऀ-ॿ]+)*", "xxx[=11=]xxx")'/>
</xsl:template>
在测试输入中这会产生:<p>xxxचाय का कपxxx means ‘cup of tea’ in xxxहिन्दिxxx.</p>
这显然是不正确的,因为印地语是用 xxx 包装的,而不是 span 标签,但从积极的方面来说,实际上发现并处理了印地语的每个区域.我无法用 span 标签替换 xxx 代码,因为那是无效的 XSLT。
这应该可行(代码后的一些注释):
XSLT 2.0
<xsl:analyze-string select="$textValue" regex="([ऀ-ॿ]+)((\s+[ऀ-ॿ]+)*)">
<xsl:matching-substring>
<span xml:lang="hi-Deva"><xsl:value-of select="regex-group(1)"/><xsl:value-of select="regex-group(2)"/></span>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
- 正则表达式是您第二次尝试的正则表达式(因为它只正确匹配印地语文本片段!),只是在第一部分周围有括号
matching-substring
分支将 span
放在印地语文本周围
non-matching-substring
分支只是 returns 未修改的 "normal" 文本子字符串(您返回的是整个文本!)
我想出了 http://xsltransform.net/jyH9rMo 正好
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<hmtl>
<head>
<title>New Version!</title>
</head>
<xsl:apply-templates/>
</hmtl>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:analyze-string select="." regex="([ऀ-ॿ]+)((\s+[ऀ-ॿ]+)*)">
<xsl:matching-substring>
<span xml:lang="hi-Deva"><xsl:value-of select="."/></span>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:transform>
补充前面的答案,您可能会注意到您可以用 \p{IsDevanagari}
代替 [ऀ-ॿ]
我正在尝试在 HTML 文档上使用 XSLT 2.0 (Saxon-PE 9.6) 来创建围绕来自指定非拉丁 Unicode 块(允许空格)的所有连续字符运行的标签。我需要将此过程应用于文档中的每个 text() 节点。我已经通过使用 <xsl:analyze-string>
和 fn:replace()
的两种方法取得了一些进展,但我无法得出令人满意的完整解决方案。
例如,这里有一些包含印地语的文本:
输入:<p>चाय का कप means ‘cup of tea’ in हिन्दि.</p>
期望输出:<p><span xml:lang="hi-Deva">चाय का कप</span> means ‘cup of tea’ in <span xml:lang="hi-Deva">हिन्दि</span>.</p>
如何在 XSLT 2.0 中实现此过程?
这是我对 <xsl:analyze-string>
的尝试:
(注意:印地语使用天城文代码块 U+0900 到 U+097F。)
<xsl:template match="text()">
<xsl:variable name="textValue" select="."/>
<xsl:analyze-string select="$textValue" regex="(\s*.*?)([ऀ-ॿ]+)((\s+[ऀ-ॿ]+)*)(\s*.*)">
<xsl:matching-substring>
<xsl:value-of select="regex-group(1)"/>
<span xml:lang="hi-Deva"><xsl:value-of select="regex-group(2)"/><xsl:value-of select="regex-group(3)"/></span>
<xsl:value-of select="regex-group(5)"/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="$textValue"/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
在测试输入中,这会产生:
<p><span xml:lang="hi-Deva">चाय का कप</span> means ‘cup of tea’ in हिन्दि.</p>
这种方法遗漏了印地语文本的第二个区域 (हिन्दि)。我需要一种方法来查找并标记所有与正则表达式匹配的事件。
我的第二种方法使用 fn:replace()
:
<xsl:template match="text()">
<xsl:value-of select='fn:replace(., "[ऀ-ॿ]+(\s+[ऀ-ॿ]+)*", "xxx[=11=]xxx")'/>
</xsl:template>
在测试输入中这会产生:<p>xxxचाय का कपxxx means ‘cup of tea’ in xxxहिन्दिxxx.</p>
这显然是不正确的,因为印地语是用 xxx 包装的,而不是 span 标签,但从积极的方面来说,实际上发现并处理了印地语的每个区域.我无法用 span 标签替换 xxx 代码,因为那是无效的 XSLT。
这应该可行(代码后的一些注释):
XSLT 2.0
<xsl:analyze-string select="$textValue" regex="([ऀ-ॿ]+)((\s+[ऀ-ॿ]+)*)">
<xsl:matching-substring>
<span xml:lang="hi-Deva"><xsl:value-of select="regex-group(1)"/><xsl:value-of select="regex-group(2)"/></span>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
- 正则表达式是您第二次尝试的正则表达式(因为它只正确匹配印地语文本片段!),只是在第一部分周围有括号
matching-substring
分支将span
放在印地语文本周围non-matching-substring
分支只是 returns 未修改的 "normal" 文本子字符串(您返回的是整个文本!)
我想出了 http://xsltransform.net/jyH9rMo 正好
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<hmtl>
<head>
<title>New Version!</title>
</head>
<xsl:apply-templates/>
</hmtl>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:analyze-string select="." regex="([ऀ-ॿ]+)((\s+[ऀ-ॿ]+)*)">
<xsl:matching-substring>
<span xml:lang="hi-Deva"><xsl:value-of select="."/></span>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:transform>
补充前面的答案,您可能会注意到您可以用 \p{IsDevanagari}
代替 [ऀ-ॿ]