在 Saxon/C 中使用条件 includes/static 参数?

Using conditional includes/static parameters in Saxon/C?

我正在尝试将 XSLT 条件 includes/static 参数与 Saxon/C HE 一起使用,但出现以下错误:

Error 
  Parameter $some_param cannot be supplied dynamically because it is declared as static

为了重现,我使用了几年前添加的几个答案中的示例。 (Here and here.)

在这两个答案中,我从命令行使用了 java 版本 9.7 的 Saxon-HE,没有任何问题。我还从命令行使用 HE 的 java 版本 10.5 再次进行了测试。再次没有问题。

但是,如果我尝试使用 Saxon/C 1.2.1 运行 Saxon-HE 9.9.1.5C 从 Python (3.8) 运行 这个例子,我得到以上错误。

有没有其他人有 XSLT 3.0 和 Saxon/C(尤其是 Python)中可以提供指导的静态参数的经验?

测试代码...

XML 输入(test.xml)

<doc>
    <foo/>
</doc>

Python

import saxonc

saxon_proc = saxonc.PySaxonProcessor(license=False)

print(f"Processor version: {saxon_proc.version}")

xsltproc = saxon_proc.new_xslt30_processor()

# noinspection PyArgumentList
xsltproc.set_parameter("inc2", saxon_proc.make_boolean_value(True))

results = xsltproc.transform_to_string(source_file="test.xml", stylesheet_file="test_main.xsl")

if results:
    print(results)

saxon_proc.release()

主 XSLT 3.0 (test_main.xsl)

<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="xs">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:param name="inc1" as="xs:boolean" select="false()" 
        static="yes" required="no"/>
    <xsl:param name="inc2" as="xs:boolean" select="false()" 
        static="yes" required="no"/>

    <xsl:include href="test_inc1.xsl" use-when="$inc1"/>
    <xsl:include href="test_inc2.xsl" use-when="$inc2"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>

第一个可能包含的 XSLT 3.0 (test_inc1.xsl)

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:template match="foo">
        <xsl:copy>INCLUDE FILE 1!!!</xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>

第二个可能包含的 XSLT 3.0 (test_inc2.xsl)

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:template match="foo">
        <xsl:copy>INCLUDE FILE 2!!!</xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>

预期输出(这是我从命令行使用 java Saxon-HE 得到的结果(如下所示))

<doc>
   <foo>INCLUDE FILE 2!!!</foo>
</doc>

实际输出

Processor version: Saxon/C 1.2.1 running with Saxon-HE 9.9.1.5C from Saxonica
Error 
  Parameter $inc2 cannot be supplied dynamically because it is declared as static

工作命令行:

java -cp "saxon-he-10.5.jar" net.sf.saxon.Transform -s:"test.xml" -xsl:"test_main2.xsl" inc2="true"

我还应该注意,我在尝试使用影子属性时遇到了同样的错误(命令行仍然可以使用命令行 arg inc_number="2"):

<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="xs">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:param name="inc_number" as="xs:string" select="'1'" static="yes" required="no"/>

    <xsl:include _href="test_inc{$inc_number}.xsl"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>

来自@ond1(O'Neil Delpratt - Saxonica)...

Hi, unfortunately it is not currently possible to set the static parameters in the current version, but I have added this feature which will be available in the next release.

因此,在支持设置静态参数之前,我将使用两个不同的“主要”XSLT;每一个都包括所需的样式表。另一种选择是在执行 XSLT 之前对其进行转换,但这两个独立的“主要”是我已经在做的事情。

此外,一旦支持设置静态参数,我将使用完整的工作示例更新此答案。

我第一次使用 SaxonC 11.1 和上面的 XSLT 代码进行测试并使用 Python API 结果是 Python 代码

from saxonc import *

with PySaxonProcessor(license=False) as proc:
    print("Test SaxonC on Python")
    print(proc.version)
    
    xslt30proc = proc.new_xslt30_processor()
    
    result = xslt30proc.transform_to_string(stylesheet_file = 'main-sheet.xsl', source_file = 'test.xml')
         
    print(result)
    
    xslt30proc.set_parameter('inc1', proc.make_boolean_value(True))
    
    result = xslt30proc.transform_to_string(stylesheet_file = 'main-sheet.xsl', source_file = 'test.xml')
  
    print(result)
    
    xslt30proc.set_parameter('inc2', proc.make_boolean_value(True))
    
    result = xslt30proc.transform_to_string(stylesheet_file = 'main-sheet.xsl', source_file = 'test.xml')
  
    print(result)

并输出

Test SaxonC on Python
SaxonC-HE 11.1 from Saxonica
source in transformFiletoString=test.xml stylsheet=main-sheet.xsl
<?xml version="1.0" encoding="UTF-8"?>
<doc>
   <foo/>
</doc>

source in transformFiletoString=test.xml stylsheet=main-sheet.xsl
<?xml version="1.0" encoding="UTF-8"?>
<doc>
   <foo>INCLUDE FILE 1!!!</foo>
</doc>

source in transformFiletoString=test.xml stylsheet=main-sheet.xsl
Warning at mode (unnamed)
  XTDE0540  Ambiguous rule match for /doc/foo[1]
Matches both "foo" on line 3 of
  file:/C:/Users/marti/OneDrive/Documents/xslt/blog-xslt-3-by-example/saxonc-11.1-python/conditional-include-with-static-params/test_inc2.xsl
and "foo" on line 3 of file:/C:/Users/marti/OneDrive/Documents/xslt/blog-xslt-3-by-example/saxonc-11.1-python/conditional-include-with-static-params/test_inc1.xsl
<?xml version="1.0" encoding="UTF-8"?>
<doc>
   <foo>INCLUDE FILE 2!!!</foo>
</doc>

或者只是您设置参数和 运行 样式表的示例:

from saxonc import *

with PySaxonProcessor(license=False) as proc:
    print("Test SaxonC on Python")
    print(proc.version)
    
    xslt30proc = proc.new_xslt30_processor()
    
    xslt30proc.set_parameter('inc2', proc.make_boolean_value(True))
    
    result = xslt30proc.transform_to_string(stylesheet_file = 'main-sheet.xsl', source_file = 'test.xml')
  
    print(result)

给予

Test SaxonC on Python
SaxonC-HE 11.1 from Saxonica
source in transformFiletoString=test.xml stylsheet=main-sheet.xsl
<?xml version="1.0" encoding="UTF-8"?>
<doc>
   <foo>INCLUDE FILE 2!!!</foo>
</doc>