
本文介绍如何利用 xslt 3 和 saxonc(通过 python 的 `saxonche` 库)对 xml 文档中嵌套在 `
` 标签内的软件名称进行语义化标注——仅在匹配 json 提供的上下文与精确文本位置时,将软件名(如 modeller)包裹进 `
在科研文献 XML 处理场景中,常需从富文本段落(如
)中精准识别并标注软件工具名称(如 MODELLER、PROSA),但难点在于:这些名称往往夹杂在带有 、 等内联标签的混合内容中,无法直接用正则或简单字符串替换;同时,标注必须严格依据预提取的结构化证据(如 jsON 中的 context 字段和 normalizedForm),确保语义准确、避免误包。
推荐方案是采用 XSLT 3 + SaxonC ——它原生支持 json 解析、高阶函数、analyze-String() 正则分词及隧道参数(tunnel parameters),能优雅解决“上下文匹配 → 文本定位 → 安全包裹”这一完整链路。
✅ 核心思路
- 上下文驱动匹配:遍历 JSON 中每个 “type”: “software” 条目,检查其 context 是否完整出现在当前
元素的扁平化文本内容中(即忽略所有子标签,只比对可见文本);
- 安全文本注入:一旦上下文匹配成功,进入 process 模式,仅对
内部的纯文本节点(text())应用逻辑;
- 精准定位与包裹:对每个文本节点,先验证其是否同时满足:
- 包含该软件的 context(保证语境一致性);
- 包含其 normalizedForm(如 “MODELLER”);
- 再调用 analyze-string(., $pattern) 进行正则匹配,确保仅包装字面完全一致的出现,避免子串误匹配(如 “MOD” 不会匹配 “MODELLER”);
- 零破坏 dom 结构:所有 、 等原有子元素保持原位,仅修改目标文本节点为
MODELLER ,尾部文本(tail)自动继承。
? 示例 XSLT 片段(关键逻辑)
⚙️ python 调用示例(使用 saxonche)
from saxonche import PySaxonProcessor proc = PySaxonProcessor(license=False) xslt = proc.new_xslt30_processor() xml_file = "input.xml" json_file = "software_mentions.json" # 编译并执行转换 executable = xslt.compile_stylesheet(stylesheet_file="wrap-software.xsl") output = executable.transform_to_string( source_file=xml_file, params={"json-doc": f"json-doc('{json_file}')"} ) print(output)
? 注意事项 必须使用 SaxonC 12+(saxonche),因仅此版本完整支持 json-doc()、analyze-string() 及 map 类型; JSON 中的 context 字段需与 XML 实际渲染文本完全一致(包括空格、标点、括号格式),建议预处理统一规范化; 若存在多个重叠软件名(如 “R” 和 “RStudio”),应按长度降序排序 JSON 条目,避免短名优先匹配导致长名截断; 对于大小写敏感场景,可在 analyze-string() 中添加 flags=”i” 并配合 upper-case() 统一比较。
该方法摒弃了易出错的手动 DOM 遍历与字符串拼接,以声明式、可验证、可复用的 XSLT 逻辑实现高精度语义标注,特别适合构建学术文献知识图谱、软件实体链接等 nlp 前处理流水线。