如何在XSLT中通过正则匹配处理@xlink:href中的DOI内容?
在XSLT 1.0中匹配并替换@xlink:href中的DOI
XSLT 1.0本身没有原生正则表达式支持,需要借助EXSLT正则扩展(主流XSLT处理器如Saxon、libxslt均支持)来实现DOI的匹配与替换。以下是具体实现方案:
前提准备
假设你有类似这样的XML输入(包含不同格式的DOI链接):
<root xmlns:xlink="http://www.w3.org/1999/xlink"> <reference xlink:href="https://doi.org/10.1513/AnnalsATS.202508-879ED">期刊引用1</reference> <reference xlink:href="10.1513/AnnalsATS.202508-879ED">期刊引用2</reference> <reference xlink:href="http://dx.doi.org/10.1513/AnnalsATS.202508-879ED?utm_source=example">期刊引用3</reference> </root>
原有的精确匹配XSLT代码通常是硬编码指定DOI值,无法适配多格式场景,我们需要改为正则匹配方案。
实现代码
以下XSLT代码会自动识别@xlink:href中的DOI(匹配10.xxx/xxxx格式的内容),并替换为你指定的目标链接格式:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:regexp="http://exslt.org/regular-expressions" extension-element-prefixes="regexp"> <!-- 匹配所有包含DOI的xlink:href属性 --> <xsl:template match="@xlink:href"> <!-- 用正则提取DOI内容:匹配10.开头,后续数字+斜杠,再到非空格/问号/井号的内容 --> <xsl:variable name="extracted-doi" select="regexp:match(., '10\.[0-9]+/[^\s?#]+')"/> <!-- 如果提取到DOI,替换为目标格式 --> <xsl:if test="$extracted-doi"> <xsl:attribute name="xlink:href"> <!-- 这里替换成你需要的目标链接,示例为统一的DOI解析地址 --> <xsl:text>https://your-custom-domain/doi/</xsl:text> <xsl:value-of select="$extracted-doi"/> </xsl:attribute> </xsl:if> <!-- 未匹配到DOI时,保留原属性值 --> <xsl:if test="not($extracted-doi)"> <xsl:copy/> </xsl:if> </xsl:template> <!-- 身份模板:复制所有未被自定义模板匹配的节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
关键说明
- 正则表达式调整:如果你的DOI包含下划线、大写字母等特殊字符,可以将正则改为
10\.[0-9a-zA-Z]+/[0-9a-zA-Z._-]+,适配更多DOI格式。 - 处理器兼容性:确保使用的XSLT处理器支持EXSLT扩展,大部分主流工具(如Saxon 6.x、libxslt)都默认支持。
- 精准替换特定DOI:如果只需要替换某个特定DOI,可在模板中添加条件判断,比如:
<xsl:if test="regexp:match(., '10\.1513/AnnalsATS\.202508-879ED')"> <!-- 执行替换逻辑 --> </xsl:if>
内容的提问来源于stack exchange,提问作者Karthick
相关产品推荐
相关产品推荐

