如何在DITA-OT日志中记录并打印指定XSLT检测错误?
解决DITA-OT自定义XSLT中检测无效xref元素的需求
需求说明
我在DITA-OT 3.4中开发了自定义插件com.myorg.dita.html5,它是org.dita.html5的扩展插件,目前配置运行正常。现在需要在主自定义XSLT中实现以下检测逻辑:
- 找出所有带有
class属性包含topic/xref的元素 - 这些元素必须包含子元素或后代元素
<data>,且该<data>的@value属性为空(无值) - 记录所有符合条件的元素实例,若存在此类错误则打印错误信息并终止DITA-OT进程
问题分析
你尝试的代码存在几个关键问题:
- XSLT变量是不可变的,无法直接在模板中追加内容到
$errorLog - 匹配条件错误:
exists(//data)会匹配整个文档的<data>,而非当前xref元素下的;not(//data/@value ='')逻辑反了,应该检测@value为空的情况 - 模式匹配的选择器和模板匹配规则不一致(一个带空格一个不带)
正确实现代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0"> <xsl:output method="html" encoding="utf-8" indent="no"/> <!-- 提前收集所有符合条件的错误元素 --> <xsl:variable name="invalidXrefs" as="element()*"> <xsl:for-each select="//*[contains(@class, ' topic/xref ')]"> <!-- 检查当前xref下是否存在@value为空(含全空格)的data元素 --> <xsl:if test=".//data[normalize-space(@value) = '']"> <xsl:sequence select="."/> </xsl:if> </xsl:for-each> </xsl:variable> <!-- 根节点处理模板 --> <xsl:template match="/"> <!-- 先执行正常的主题转换逻辑 --> <xsl:apply-templates/> <!-- 检查错误并触发终止 --> <xsl:if test="$invalidXrefs"> <xsl:message terminate="Yes"> <xsl:text>检测到无效的xref元素(包含空value的data子元素):</xsl:text> <xsl:for-each select="$invalidXrefs"> <xsl:text> - 位置:</xsl:text> <xsl:value-of select="base-uri()"/> <xsl:text> 行号:</xsl:text> <xsl:value-of select="line-number()"/> <xsl:text> 元素:</xsl:text> <xsl:copy-of select="."/> </xsl:for-each> </xsl:message> </xsl:if> </xsl:template> </xsl:stylesheet>
代码说明
- 使用变量
$invalidXrefs提前收集所有错误元素,规避XSLT变量不可变的限制 - 匹配条件优化:
contains(@class, ' topic/xref ')(带前后空格)精准匹配DITA标准的class属性格式.//data[normalize-space(@value) = '']仅检查当前xref元素下的后代data,同时处理空字符串或全空格的情况
- 错误信息中添加元素的URI和行号,方便快速定位问题
- 通过
<xsl:message terminate="Yes"/>直接触发DITA-OT进程终止
内容的提问来源于stack exchange,提问作者user19732805
相关产品推荐
相关产品推荐

