如何在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(.,'(©)'))"> <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接收外部传入参数+条件判断调用模板的方式实现,步骤如下:
- 在XSL的根节点下、和现有全局变量同级的位置,声明全局参数用于接收命令行传入的开关值,默认设为
true()表示默认执行所有校验:
<xsl:param name="run.affd" select="true()"/> <xsl:param name="run.affc" select="true()"/> <xsl:param name="run.copy" select="true()"/>
- 修改根模板中调用三个模板的代码,增加条件判断,只有对应参数为
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>
- 命令行运行时,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
相关产品推荐
相关产品推荐

