如何在 DITA-OT 日志中记录和打印消息?

问题描述 投票:0回答:1

我在 DITA-OT 3.4 中创建了一个名为 com.myorg.dita.html5 的自定义插件,它是基本插件 org.dita.html5 的扩展。该插件已正确设置并按预期运行。

在此插件的主要自定义 XSLT 文件中,我通过使用 匹配根节点来处理每个主题。插件中还有其他 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-2.0 dita-ot
1个回答
0
投票

这听起来好像 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>
© www.soinside.com 2019 - 2024. All rights reserved.