Saxon-js 是否对 xsl:param 执行 XML 语法检查?

Does Saxon-js perform XML syntax checking on a xsl:param?

提问人:ImTalkingCode 提问时间:5/31/2021 更新时间:5/31/2021 访问量:218

问:

我通过 Saxon-js 运行这个 XSL 脚本。它使用在转换调用中使用 stylesheetParams 收到的 XML 来更新主输入 XHTML 上的 cost 字段。都很好。问题在于没有对 param-XML 进行语法检查(您可以在注释掉的行中看到它的样子)。它位于 XHTML 上,转换将生成错误,但不会在 param-XML 上生成错误。它只是允许它进入,然后键函数只是不更新 XHTML。有没有办法在同一个转换调用中检查格式正确的XML参数,或者我是否必须使用2个转换调用:在param-XSL上调用transform进行语法检查,然后调用此主转换来更新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>
节点.js xslt xhtml saxon-js

评论


答:

2赞 Michael Kay 5/31/2021 #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() 需要字符串中的词法 XML。调用此节点树的效果是首先原子化节点,生成非类型化原子值“32134112.99”,然后尝试将此字符串“32134112.99”解析为词法 XML,这应该会失败。fn:parse-xml($cost-data)fn:parse-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看到数据之前很久就执行了它。

评论

0赞 ImTalkingCode 5/31/2021
cost-data 来自转换调用的 stylesheetParams。XSL 中的 XML 只是一个注释,只是为了显示结构。
0赞 Michael Kay 5/31/2021
感谢您提供额外的信息,这完全改变了问题;-(。如果参数以包含词法 XML 的字符串形式提供,则 parse-xml() 将检查它。如果它以节点树的形式提供,则 parse-xml() 将失败。您绝对应该使用属性 on 来指示预期值是字符串还是节点树。asxsl:param
0赞 ImTalkingCode 6/1/2021
我将上面的 xsl:param 行更改为 <xsl:param name=“cost-data” as=“document-node()”>并且没有区别。无论我如何搞砸传入的<供应商>XML,Saxon-js都不会产生错误。此外,Saxon 文档说 fn:parse-xml 接受 as:string 参数。
0赞 ImTalkingCode 6/1/2021
还尝试了<xsl:param name=“cost-data” as=“xs:string”/>。相同的结果。
0赞 Michael Kay 6/1/2021
您需要提供一个重现,以显示您要传递给参数的值。另外:无论是在浏览器中(如果是这样,在哪个浏览器中)还是在 node.js 中,这都可能是相关的,因为这会影响用于 parse-xml() 函数的 XML 解析器 - 不幸的是,它们都以略有不同的方式报告错误。