如何通过XSLT将XML文档名称的数字部分添加到元素ID中
解决方案:用XSLT更新XML元素的ID属性(从文件名提取数字)
没问题,我来帮你搞定这个需求。下面是一个XSLT实现方案,能自动从文档文件名里提取数字部分(比如你例子里的52),然后把它加到每个<w>元素的id属性里:
完整XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 身份模板:默认复制所有节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 专门处理<w>元素,修改它的id属性 --> <xsl:template match="w/@id"> <!-- 第一步:从文档URI中提取文件名里的数字部分 --> <xsl:variable name="doc-filename" select="tokenize(document-uri(), '/')[last()]"/> <xsl:variable name="doc-number" select="replace($doc-filename, '.*-(\d+)\.xml$', '$1')"/> <!-- 第二步:重构id属性值 --> <xsl:attribute name="id"> <xsl:value-of select="replace(., 'w_(\d+)', concat('w_', $doc-number, '_$1'))"/> </xsl:attribute> </xsl:template> </xsl:stylesheet>
代码说明
- 身份模板:这是XSLT里的基础模板,会原样复制XML里的所有节点和属性,确保除了我们要修改的
<w>的id之外,其他内容都保持不变。 - 提取文档编号:
- 用
document-uri()获取当前处理的XML文件的完整路径,然后用tokenize(..., '/')[last()]截取最后一段(也就是文件名)。 - 用
replace()函数配合正则表达式.*-(\d+)\.xml$,从文件名里提取出数字部分(比如从document-a-f-52.xml里拿到52)。这个正则的意思是:匹配所有内容直到最后一个-,然后捕获后面的数字,直到.xml结尾。
- 用
- 重构ID属性:再次用
replace()函数,把原来的id值(比如w_1)替换成w_文档编号_数字的格式(比如w_52_1)。
测试结果
用你提供的输入XML运行这个XSLT后,输出会是:
<?xml version="1.0" encoding="UTF-8"?> <ws> <w id="w_52_1">how</w> <w id="w_52_2">to</w> <w id="w_52_3">add</w> <w id="w_52_4">document</w> <w id="w_52_5">number</w> <w id="w_52_6">to</w> <w id="w_52_7">this</w> <w id="w_52_8">.</w> </ws>
注意事项
- 这个方案基于XSLT 2.0及以上版本,因为用到了
tokenize()和带正则的replace()函数。如果你的环境只能用XSLT 1.0,可以告诉我,我再给你调整适配1.0的版本。 - 正则表达式
.*-(\d+)\.xml$假设你的文件名格式是[前缀]-[数字].xml,如果文件名格式有变化(比如数字位置不同),可以调整正则来匹配你的实际格式。
内容的提问来源于stack exchange,提问作者Lena S
相关产品推荐
相关产品推荐

