如何使用XSLT读取XML的DOCTYPE声明并校验指定DTD?
用XSLT读取XML的DOCTYPE声明并检查指定DTD
核心问题拆解
你需要读取XML的DOCTYPE声明,判断是否包含目标JATS DTD(公共标识符:-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD with OASIS Tables with MathML3 v1.1 20151215//EN,系统标识符:JATS-archive-oasis-article1-mathml3.dtd),满足条件则输出对应元素。此前使用unparsed-text()/unparsed-text-lines()本地有效但流水线环境失效,同时对Saxon的schema()函数的适用性存疑。
可行解决方案
方案1:标准XSLT文档节点属性(推荐,无扩展依赖)
XML解析后,文档节点(/)的DOCTYPE信息可通过标准XSLT 2.0+函数直接获取,无需读取原始文本,完美规避流水线文件访问问题:
<xsl:template match="/"> <xsl:if test="public-id(/) = '-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD with OASIS Tables with MathML3 v1.1 20151215//EN' and system-id(/) = 'JATS-archive-oasis-article1-mathml3.dtd'"> <!-- 满足条件时生成的目标元素 --> <valid-jats-dtd/> </xsl:if> </xsl:template>
public-id(/):获取DOCTYPE的公共标识符system-id(/):获取DOCTYPE的系统标识符(即DTD文件名)
方案2:修复unparsed-text()流水线失效问题
若必须采用文本读取方式,失效原因通常是路径解析错误或权限限制:
- 改用流水线环境支持的绝对URI或统一资源路径,避免相对路径
- 检查Saxon安全配置,确认允许读取外部文本文件(部分流水线会限制文件系统访问)
关于saxon:schema()函数的说明
该函数仅用于处理XML Schema(XSD),完全不适用于DTD场景,它的作用是加载XSD模式并获取模式元数据,和DOCTYPE/DTD检查无关,无需考虑。
关键注意事项
- 确保使用支持XSLT 2.0及以上版本的处理器(如Saxon HE/PE/EE),
public-id()和system-id()是XSLT 2.0引入的标准函数 - 流水线环境优先选择方案1,避免文件读取带来的兼容性问题
内容的提问来源于stack exchange,提问作者GreatPretender
相关产品推荐
相关产品推荐

