我在 DITA-OT 3.4 中创建了一个名为 com.myorg.dita.html5 的自定义插件,它是基本插件 org.dita.html5 的扩展。该插件已正确设置并按预期运行。
在此插件的主要自定义 XSLT 文件中,我通过使用
我当前的挑战是;我需要找到所有具有
class=topic/xref
的元素,其中 <data>
元素作为子元素或后代,并且在 @value 属性中没有任何值。我需要记录整个 dita-ot 过程中的所有此类情况。如果记录了任何错误,则打印它并终止 dita-ot 进程。如果可能的话,我需要在这个 XSL 中执行此操作。
我的原始xsl:
<?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"/>
<!-- root rule -->
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
我正在尝试:
<?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" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="xs exsl" version="2.0">
<xsl:output method="html" encoding="utf-8" indent="no"/>
<xsl:variable name="errorLog" as="element()*"/>
<!-- root rule -->
<xsl:template match="/">
<xsl:apply-templates/>
<xsl:apply-templates select="//*[contains(@class, ' topic/xref ')]" mode="test"/>
<xsl:if test="$errorLog">
<!-- Print the errors -->
<xsl:message terminate="Yes">
<xsl:text>List of all the errors </xsl:text>
<xsl:copy-of select="$errorLog"/>
</xsl:message>
</xsl:if>
</xsl:template>
<xsl:template match="*[contains(@class, 'topic/xref')]" mode="test">
<xsl:if test="exists(//data) and not(//data/@value ='')">
<!-- Append the error to the errorLog variable -->
<xsl:copy-of select="."/>
<xsl:sequence select="$errorLog, current()"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
如何实现这一目标?
这听起来好像 XSLT 3.0 累加器可以提供帮助。 XSLT 2 和 DITA-OT 通常与 Saxon 一起运行,目前支持的 Saxon 版本是 10、11、12,无论如何它们都是 XSLT 3.0 处理器,只是通过向后兼容性支持 XSLT 2 样式表。
所以你可以尝试例如
<?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" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="xs exsl" version="3.0">
<xsl:output method="html" encoding="utf-8" indent="no"/>
<xsl:accumulator name="errorLog" as="element()*" initial-value="()">
<xsl:accumulator-rule match="*[contains(@class, 'topic/xref')][exists(//data) and not(//data/@value ='')]" select="$value, ."/>
</xsl:accumulator>
<!-- root rule -->
<xsl:template match="/">
<xsl:apply-templates/>
<xsl:apply-templates select="//*[contains(@class, ' topic/xref ')]" mode="test"/>
<xsl:if test="accumulator-after('errorLog')">
<!-- Print the errors -->
<xsl:message terminate="Yes">
<xsl:text>List of all the errors </xsl:text>
<xsl:copy-of select="accumulator-after('errorLog')"/>
</xsl:message>
</xsl:if>
</xsl:template>
<xsl:mode name="test" on-no-match="shallow-skip" use-accumulators="errorLog"/>
<xsl:mode use-accumulators="errorLog"/>
</xsl:stylesheet>
请注意,我在累加器规则中使用了原始代码中的条件,例如
<xsl:accumulator name="errorLog" as="element()*" initial-value="()">
<xsl:accumulator-rule match="*[contains(@class, 'topic/xref')][exists(//data) and not(//data/@value ='')]" select="$value, ."/>
</xsl:accumulator>
但我怀疑你更想要
<xsl:accumulator name="errorLog" as="element()*" initial-value="()">
<xsl:accumulator-rule match="*[contains(@class, 'topic/xref')][exists(.//data) and not(.//data/@value ='')]" select="$value, ."/>
</xsl:accumulator>