Saxon-JS是否对xsl:param执行XML语法校验?如何在单次转换中完成校验?
结论
可以在同一次transform调用中完成参数XML的合法性校验,不需要拆分两次转换。
你遇到的无报错问题核心原因是:当前你仅在td模板的匹配条件和输出逻辑中才调用fn:parse-xml($cost-data),如果解析失败,匹配条件直接不成立,模板不会执行,自然不会抛出显性错误。
实现方案
你可以在初始模板入口处先完成cost-data参数的解析、语法校验和结构校验,校验不通过时主动抛出错误即可,修改后的示例代码如下:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:err="http://www.w3.org/2005/xqt-errors" exclude-result-prefixes="#all" expand-text="yes"> <xsl:output method="html" omit-xml-declaration="yes" encoding="UTF-8" include-content-type="no"/> <xsl:param name="cost-data"/> <!-- <supplier><product><key>3</key><pcost uptype="1"><key>21341</key><cost>12.99</cost></pcost></product></supplier> --> <xsl:key name="cost" match="product/pcost[@uptype = 1]/cost" use="'cost' || ancestor::product/key"/> <xsl:mode on-no-match="shallow-copy"/> <xsl:template match="td[@name][key('cost', @name, $parsed-cost-data)]/text()">{key('cost', ../@name, $parsed-cost-data)}%</xsl:template> <xsl:template match="/" name="xsl:initial-template"> <!-- 第一步:校验XML语法合法性 --> <xsl:variable name="parsed-cost-data" as="document-node()"> <xsl:try> <xsl:sequence select="fn:parse-xml($cost-data)"/> <xsl:catch> <xsl:message terminate="yes">成本数据XML语法错误:{$err:description}</xsl:message> </xsl:catch> </xsl:try> </xsl:variable> <!-- 第二步:校验XML结构合法性,可根据你的业务规则调整校验逻辑 --> <xsl:choose> <xsl:when test="not($parsed-cost-data/supplier/product)"> <xsl:message terminate="yes">成本数据XML结构错误:缺少必填的supplier/product节点</xsl:message> </xsl:when> <xsl:when test="exists($parsed-cost-data/supplier/product[not(key) or not(pcost[@uptype=1]/cost)])"> <xsl:message terminate="yes">成本数据XML结构错误:存在product节点缺少key或合法的pcost成本节点</xsl:message> </xsl:when> </xsl:choose> <!-- 校验通过后执行正常转换逻辑 --> <xsl:next-match/> </xsl:template> </xsl:stylesheet>
优化说明
- 提前解析的
$parsed-cost-data可以全局复用,避免原来写法中每次匹配td都重复解析XML的性能损耗 - 校验逻辑可以根据你的实际业务规则灵活扩展,比如校验cost节点的值是否为合法数字等
terminate="yes"会直接终止转换并抛出错误,你也可以根据需求调整为返回错误提示的XHTML内容,而非直接终止转换
内容的提问来源于stack exchange,提问作者ImTalkingCode
相关产品推荐
相关产品推荐

