You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在XSLT运行命令中跳过指定名称的模板执行

问题描述

我正在尝试使用XSL对XML文件进行校验,并将校验日志输出为HTML报告。当前所用XSL文件包含三个命名模板,名称分别为affd、affc和copy,目前通过如下运行命令执行转换流程:

java -jar saxon8.9.0.jar -o aaam-003-vtout.html AAM-01-2019-0003.xml identity.xsl -l

需求是可以直接通过运行命令跳过或忽略某一模板的执行,例如不需要运行affd模板时,如何在XSL命令行中配置实现。

当前使用的XSL代码如下:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"    xmlns:exsl="http://exslt.org/common"    xmlns:xlink="http://www.w3.org/1999/xlink"      xmlns:mml="http://www.w3.org/1998/Math/MathML"  xmlns:saxon="http://saxon.sf.net/"  xmlns:file="java.io.File"   xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="exsl file" extension-element-prefixes="saxon"  version='2.0'>
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
    <xsl:variable name="aff-count" select="1" saxon:assignable="yes"/>
    <xsl:variable name="copyright-count" select="1" saxon:assignable="yes"/>
    <xsl:template match="/">
        <html>
            <title>Log Report</title>
            <style>table {  border-collapse: collapse;  }   table, th, td { border: 1px solid black;    }   thead {background: #bed3fa}</style>
            <body>
                <h1 align="center">Log Report</h1>
                <hr/>
                <br/>
                <table align="center" border="none" width="100%">
                    <thead>
                        <tr style="font-size:14pt; font-weight:bold;" border="solid thin;">
                            <th>Check ID</th>
                            <th>Element Name</th>
                            <th>Error Description</th>
                            <th>Error Position</th>
                        </tr>
                    </thead>
                    <tbody>
                        <xsl:call-template name="affd"/>
                        <xsl:call-template name="affc"/>
                        <xsl:call-template name="copy"/>
                    </tbody>
                </table>
            </body>
        </html>
    </xsl:template>
    <!--Affiliation Department check-->
    <xsl:template name="affd">
        <xsl:for-each select="descendant::*">
            <xsl:choose>
                <xsl:when test="matches(local-name(),'aff')">
                    <xsl:if test="not(matches(.,'(xxx)'))">
                        <tr>
                            <td>AFF<xsl:value-of select="$aff-count"/>
                            </td>
                            <saxon:assign name="aff-count" select="$aff-count+1"/>
                            <td>
                                <xsl:value-of select="name()"/>
                            </td>
                            <td>
                                <xsl:text>"D" missing</xsl:text>
                            </td>
                            <td>
                                <xsl:value-of select="@error-position"/><xsl:value-of select="saxon:line-number()"/>:<xsl:value-of select="saxon:column-number()"/>
                            </td>
                        </tr>
                    </xsl:if>
                </xsl:when>
            </xsl:choose>
        </xsl:for-each>
    </xsl:template>
    <!--Affiliation city and country check-->
    <xsl:template name="affc">
        <xsl:for-each select="descendant::*">
            <xsl:choose>
                <xsl:when test="matches(local-name(),'aff')">
                    <xsl:if test="not(descendant::*:c)">
                        <tr>
                            <td>AFF2<xsl:value-of select="$aff-count"/>
                            </td>
                            <saxon:assign name="aff-count" select="$aff-count+1"/>
                            <td>c</td>
                            <td>C missing</td>
                            <td>
                                <xsl:value-of select="@error-position"/>
                            </td>
                        </tr>
                    </xsl:if>
                </xsl:when>
            </xsl:choose>
        </xsl:for-each>
    </xsl:template>
    <!--Copyright symbol in Copyright tag-->
    <xsl:template name="copy">
        <xsl:for-each select="descendant::*">
            <xsl:choose>
            <xsl:when test="matches(local-name(),'copy')">
            <xsl:if test="not(matches(.,'(&#x00A9;)'))">
                  <tr>
                    <td>CPY<xsl:value-of select="$copy"/></td>
                    <saxon:assign name="copy" select="$copy+1"/>
                    <td><xsl:value-of select="name()"/></td>
                    <td><xsl:text>Copy missing</xsl:text></td>
                    <td><xsl:value-of select="@error-position"/></td>
                  </tr>
              </xsl:if>
              </xsl:when>
            </xsl:choose>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
实现方案

Saxon本身没有提供直接在命令行跳过指定命名模板调用的参数,要实现命令行控制模板是否执行,需要通过XSL接收外部传入参数+条件判断调用模板的方式实现,步骤如下:

  1. 在XSL的根节点下、和现有全局变量同级的位置,声明全局参数用于接收命令行传入的开关值,默认设为true()表示默认执行所有校验:
<xsl:param name="run.affd" select="true()"/>
<xsl:param name="run.affc" select="true()"/>
<xsl:param name="run.copy" select="true()"/>
  1. 修改根模板中调用三个模板的代码,增加条件判断,只有对应参数为true时才调用对应模板:
<tbody>
    <xsl:if test="$run.affd">
        <xsl:call-template name="affd"/>
    </xsl:if>
    <xsl:if test="$run.affc">
        <xsl:call-template name="affc"/>
    </xsl:if>
    <xsl:if test="$run.copy">
        <xsl:call-template name="copy"/>
    </xsl:if>
</tbody>
  1. 命令行运行时,Saxon通过参数名=值的格式传入参数,不需要执行某个模板时,把对应参数设为false()即可。例如要跳过affd模板,执行命令如下:
java -jar saxon8.9.0.jar -o aaam-003-vtout.html AAM-01-2019-0003.xml identity.xsl -l run.affd=false()

如果要同时跳过多个模板,直接在命令后追加参数即可,比如同时跳过affd和copy:

java -jar saxon8.9.0.jar -o aaam-003-vtout.html AAM-01-2019-0003.xml identity.xsl -l run.affd=false() run.copy=false()

补充说明:现有代码里copy模板存在变量定义问题,调用了$copy变量但只声明了$copyright-count,运行时会报错,需要补全对应变量声明或者修正变量名。


内容的提问来源于stack exchange,提问作者BWin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 04:12:22