在 Saxon/C 中使用条件包含/静态参数?

Posted

技术标签:

【中文标题】在 Saxon/C 中使用条件包含/静态参数?【英文标题】:Using conditional includes/static parameters in Saxon/C? 【发布时间】:2021-07-18 01:43:48 【问题描述】:

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

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

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

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

但是,如果我尝试使用运行 Saxon-HE 9.9.1.5C 的 Saxon/C 1.2.1 从 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>

【问题讨论】:

我认为在 Java API 中设置静态参数需要在编译 XsltCompiler 之前进行。我不确定它应该如何在 XsltCompiler 似乎没有作为一个类公开的 C++ 或 Python API 中工作。也许,在xsltproc = saxon_proc.new_xslt30_processor()xsltproc.set_parameter("inc2", saxon_proc.make_boolean_value(True)) 之后首先调用compile 方法,例如xsltproc.compile_stylesheet(stylesheet_file="test_main.xsl")。我还没有测试过这是否会有所改善。 C++ 和 Java 粘合代码 saxonica.plan.io/projects/saxon/repository/he/revisions/master/… 似乎在处理静态参数方面做出了一些努力,但我不确定 Python 的哪个代码路径会导致它的使用。希望稍后您能得到 Saxonica 的答复。 感谢@MartinHonnen 使用.compile_stylesheet() 是一个很好的建议,但不幸的是我仍然遇到同样的错误。 您好,很遗憾,当前版本目前无法设置静态参数,但我已添加此功能,将在下一个版本中提供。 谢谢@ond1,我会留意下一个版本。同时,我将只使用不太理想的方法,即使用不同的主 XSLT;每个包含一个。 【参考方案1】:

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

您好,很遗憾,目前无法设置静态 当前版本中的参数,但我添加了此功能 将在下一个版本中提供。

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

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

【讨论】:

以上是关于在 Saxon/C 中使用条件包含/静态参数?的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 中“有条件地”提供静态文件

在 expression.call 中使用参数调用静态方法

如何使用cmake生成基于静态库的动态链接库

24.FastAPI静态文件

如何理解CMake文档,优先静态库,Cuda混编

将 C# 对象(包含静态对象成员)作为参数传递给 C++/CLI 程序