如何用XSL将XML中@e后的文本包裹在<apiname>标签中?
问题与解决方案
需求
现有如下XML内容:
<p>This is a @e function that does stuff.</p> <p>This is also a @e function</p>
需通过XSL 2.0将@e后的目标字符串(可动态变化,示例中为function)包裹在<apiname>标签中,预期输出:
<p>This is a <apiname>function</apiname> that does stuff.</p> <p>This is also a <apiname>function()</apiname></p>
注意事项:
<p>标签内允许存在多个<apiname>标签- 原实现代码在
@e 目标字符串位于段落末尾时失效 - 无法直接修改源XML,需通过XSL处理(基于DITA Open Toolkit工作流)
有效XSL实现
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 复制所有节点,仅处理p标签内的文本内容 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 解析p标签文本,匹配并替换@e后的API名称 --> <xsl:template match="p/text()"> <xsl:analyze-string select="." regex="@e (\w+)(\(\))?"> <xsl:matching-substring> <apiname> <xsl:value-of select="regex-group(1)"/> <xsl:if test="regex-group(2)"> <xsl:value-of select="regex-group(2)"/> </xsl:if> </apiname> </xsl:matching-substring> <xsl:non-matching-substring> <xsl:value-of select="."/> </xsl:non-matching-substring> </xsl:analyze-string> </xsl:template> </xsl:stylesheet>
方案说明
- 采用
analyze-string进行全局正则匹配,解决了原代码在段落末尾无法匹配的问题,无论@e ...出现在段落任意位置都能捕获 - 正则表达式
@e (\w+)(\(\))?可匹配@e后跟字母数字组成的API名称,同时兼容带()的格式 - 保留原段落中未匹配的所有文本内容,支持多个API名称的批量处理
- 基于XSL 2.0标准,适配DITA Open Toolkit的转换工作流
内容的提问来源于stack exchange,提问作者Amy Higgins
相关产品推荐
相关产品推荐

