如何在XSLT任务中指定多个文件作为xmlSource?
如何用Saxon-JS + VS Code任务批量合并XML到单个HTML?
问题场景
当前使用VS Code搭配XSLT/XPath扩展,通过tasks.json调用Saxon-JS可正常完成单个XML到HTML的转换,但需要处理多个同模板XML文件并合并输出为单个HTML。尝试用通配符briefe/**/*.xml作为xmlSource触发文件不存在错误,因为该字段仅支持字符串输入,无法直接传入文件数组。
单个文件的有效tasks.json配置如下:
{ "version": "2.0.0", "tasks": [ { "type": "xslt-js", "label": "Saxon-JS Transform (Briefe)", "xsltFile": "briefe/tei_to_html.xsl", "xmlSource": "briefe/3690096/3690096.xml", "resultPath": "edition.html", "group": { "kind": "build", "isDefault": true }, "problemMatcher": [ "$saxon-xslt-js" ] } ] }
可行解决方案:通过JSON源批量加载XML
利用Saxon-JS支持JSON输入的特性,结合XSLT 3.0的文件处理能力实现批量合并,具体步骤如下:
1. 创建XML文件列表JSON
在briefe目录下生成list.json,手动或自动列出所有目标XML路径:
{ "xmlFiles": [ "briefe/3690096/3690096.xml", "briefe/xxx/xxx.xml", "briefe/yyy/yyy.xml" ] }
2. 修改tasks.json启用JSON源
更新任务配置,开启useJsonSource并指定JSON文件作为输入:
{ "version": "2.0.0", "tasks": [ { "type": "xslt-js", "label": "Saxon-JS Transform (Merge Briefe)", "xsltFile": "briefe/tei_to_html.xsl", "useJsonSource": true, "xmlSource": "briefe/list.json", "resultPath": "edition.html", "group": { "kind": "build", "isDefault": true }, "problemMatcher": [ "$saxon-xslt-js" ] } ] }
3. 修改XSLT样式表处理批量XML
在XSLT中解析JSON列表,逐个加载XML文件并应用转换模板:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 根模板:解析JSON并遍历XML文件 --> <xsl:template match="/"> <html> <head> <!-- 保留原有头部样式配置 --> </head> <body> <!-- 将JSON转换为XML结构,遍历文件列表 --> <xsl:variable name="json-node" select="json-to-xml(.)"/> <xsl:for-each select="$json-node/*:map/*:array/*:string"> <!-- 加载对应XML文件并应用原有模板 --> <xsl:apply-templates select="document(.)"/> </xsl:for-each> </body> </html> </xsl:template> <!-- 保留原有XML节点转换模板 --> <xsl:template match="你的目标XML节点"> <!-- 原有转换逻辑 --> </xsl:template> </xsl:stylesheet>
可选:自动生成XML列表JSON
若XML文件较多,可添加前置任务自动生成list.json,避免手动维护:
- 创建Node.js脚本
generate-xml-list.js:
const fs = require('fs'); const path = require('path'); const xmlFiles = []; const targetDir = './briefe'; function scanDir(dir) { const files = fs.readdirSync(dir); files.forEach(file => { const fullPath = path.join(dir, file); const stats = fs.statSync(fullPath); if (stats.isDirectory()) { scanDir(fullPath); } else if (path.extname(file) === '.xml') { xmlFiles.push(fullPath.replace(/\\/g, '/')); } }); } scanDir(targetDir); fs.writeFileSync('./briefe/list.json', JSON.stringify({ xmlFiles }, null, 2));
- 更新
tasks.json添加前置依赖:
{ "version": "2.0.0", "tasks": [ { "label": "Generate XML List", "type": "shell", "command": "node generate-xml-list.js", "problemMatcher": [] }, { "type": "xslt-js", "label": "Saxon-JS Transform (Merge Briefe)", "xsltFile": "briefe/tei_to_html.xsl", "useJsonSource": true, "xmlSource": "briefe/list.json", "resultPath": "edition.html", "group": { "kind": "build", "isDefault": true }, "dependsOn": ["Generate XML List"], "problemMatcher": [ "$saxon-xslt-js" ] } ] }
内容的提问来源于stack exchange,提问作者sleepyhead
相关产品推荐
相关产品推荐

