Saxon-js 是不是对 xsl:param 执行 XML 语法检查?
Posted
技术标签:
【中文标题】Saxon-js 是不是对 xsl:param 执行 XML 语法检查?【英文标题】:Does Saxon-js perform XML syntax checking on a xsl:param?Saxon-js 是否对 xsl:param 执行 XML 语法检查? 【发布时间】:2021-08-18 09:02:37 【问题描述】:我通过 Saxon-js 运行这个 XSL 脚本。它使用在使用 stylesheetParams 的转换调用中接收到的 XML 更新主输入 Xhtml 上的成本字段。都好。问题是没有对 param-XML 进行语法检查(您可以在注释掉的行中看到它的样子)。它在 XHTML 上,转换会生成错误,但不会在 param-XML 上。它只是允许它进入,然后键功能不会更新 XHTML。有没有办法在同一个转换调用中检查格式正确的 XML 参数,还是我必须使用 2 个转换调用:在 param-XSL 上调用转换进行语法检查,然后调用这个主转换来更新 XHTML ?
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
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:param> -->
<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, fn:parse-xml($cost-data))]/text()">key('cost', ../@name, fn:parse-xml($cost-data))%</xsl:template>
<xsl:template match="/" name="xsl:initial-template">
<xsl:next-match/>
</xsl:template>
</xsl:stylesheet>
【问题讨论】:
【参考方案1】:如果你的样式表代码是
<xsl:param name="cost-data">
<supplier><product><key>3</key><pcost uptype="1"><key>21341</key>
<cost>12.99</cost></pcost></product></supplier>
</xsl:param>
那么这就是格式良好的 XML,应该不会报告错误。
但是,fn:parse-xml($cost-data)
是错误的。参数的值是节点树,而不是字符串,并且 fn:parse-xml() 期望字符串中的词法 XML。在此节点树上调用fn:parse-xml()
的效果将是首先原子化该节点,生成无类型的原子值“32134112.99”,然后尝试将这个字符串“32134112.99”解析为词法 XML,这应该会失败。
为避免此类混淆,最好始终声明参数的预期类型,例如as="xs:string"
或as="document-node()"
。
如果您希望 $cost-data 的默认值是包含词法 XML 的字符串,请尝试
<xsl:param name="cost-data" as="xs:string"><![CDATA[
<supplier><product><key>3</key><pcost uptype="1"><key>21341</key>
<cost>12.99</cost></pcost></product></supplier>
]]></xsl:param>
全部在一行上,没有空格(或者如果您需要空格以提高可读性,请将其放在“>”分隔符之前)。
注意:您的问题的字面答案是:不。Saxon-JS 不执行此检查。 XML 解析器执行它,早在 Saxon-JS 看到数据之前。
【讨论】:
成本数据来自转换调用的 stylesheetParams。 XSL 中的 XML 只是一个注释,只是为了显示结构。 感谢您提供的额外信息,这完全改变了问题;-(。如果参数作为包含词法 XML 的字符串提供,则 parse-xml() 将对其进行检查。如果提供为节点树,然后 parse-xml() 将失败。您绝对应该在xsl:param
上使用as
属性来指示预期值是字符串还是节点树。
我将上面的 xsl:param 行更改为
也试过 。结果相同。
您需要提供一个重现,以显示您传递给参数的值。另外:这可能是在浏览器中(如果是的话,是哪个浏览器)还是在 node.js 中,因为这会影响用于 parse-xml() 函数的 XML 解析器 - 不幸的是,它们都报告的错误略有不同方式。以上是关于Saxon-js 是不是对 xsl:param 执行 XML 语法检查?的主要内容,如果未能解决你的问题,请参考以下文章