Menzo Windhouwer
Menzo Windhouwer

Reputation: 3

saxonche 12.4.2: passing an array as parame to PyXslt30Processor leads to AttributeError: 'saxonche.PyXdmArray' object has no attribute 'derivedaptr'

I'm trying to pass an array to a stylesheet:

`

with PySaxonProcessor(license=False) as proc:
    print(proc.version)
    xsltproc = proc.new_xslt30_processor()
    xsltproc.set_cwd(os.getcwd())
    executable = xsltproc.compile_stylesheet(stylesheet_file="cat.xsl")

    value = proc.make_array([proc.make_integer_value(i) for i in [8,9,10]])
    print(value)
    executable.set_parameter("values", value)

    result = executable.apply_templates_returning_string(source_file="person.xml")
    print(result)

`

However, this results in:

    SaxonC-HE 12.4.2 from Saxonica
    [8,9,10]
    Traceback (most recent call last):
        File "/Users/menzowi/Temp/saxontest/saxon.py", line 22, in <module>
        executable.set_parameter("values", value)
     File "python_saxon/saxonc.pyx", line 1958, in saxonche.PyXsltExecutable.set_parameter
     AttributeError: 'saxonche.PyXdmArray' object has no attribute 'derivedaptr'

I expected a result an XML document with each of the values in the array multiplied by 3. Using this stlesheet:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
    <xsl:param name="values" select="(2, 3, 4, 5)"/>
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="*">
        <output>
            <xsl:for-each select="$values">
                <out>
                    <xsl:value-of select=". * 3"/>
                </out>
            </xsl:for-each>
        </output>
    </xsl:template>
</xsl:stylesheet>

Upvotes: 0

Views: 103

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167401

Your (XSLT) code seems to try to process a sequence of (integer) values; for that I suggest you use a PyXdmValue, as shown below:

from saxonche import PySaxonProcessor, PyXdmValue

with PySaxonProcessor(license=False) as proc:
    print(proc.version)
    xsltproc = proc.new_xslt30_processor()
    executable = xsltproc.compile_stylesheet(stylesheet_file="sheet2.xsl")

    result = executable.apply_templates_returning_string(source_file="sample1.xml")
    print(result)

    value = PyXdmValue()

    for n in [8,9,10]:
        value.add_xdm_item(proc.make_integer_value(n))

    print(value)
    executable.set_parameter("values", value)

    result = executable.apply_templates_returning_string(source_file="sample1.xml")
    print(result)

As for passing an array, that seems to be a bug in SaxonC: https://saxonica.plan.io/issues/6335. As a workaround, you could pass the array to XPath evaluation calling fn:transform e.g.

value = saxon_proc.make_array([saxon_proc.make_integer_value(i) for i in [8,9,10]])

xpath_processor = saxon_proc.new_xpath_processor()

xpath_processor.set_parameter('values', value)

xdm_result = xpath_processor.evaluate("""
  transform(
    map { 
      'stylesheet-location' : 'sheet1.xsl',
      'delivery-format' : 'serialized', 
      'stylesheet-params' : map { QName('', 'values') : $values } 
    }
  )?output
""")

print(xdm_result)

Sample stylesheet processing an array (of integers) instead of a sequence is as follows:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="3.0"
    exclude-result-prefixes="#all">
    <xsl:param name="values" as="array(*)" select="[2, 3, 4, 5]"/>
    <xsl:output method="xml" indent="yes"/>
    <xsl:template name="xsl:initial-template">
        <output>
            <xsl:for-each select="$values?*">
                <out>
                    <xsl:value-of select=". * 3"/>
                </out>
            </xsl:for-each>
        </output>
    </xsl:template>
</xsl:stylesheet>

Upvotes: 1

Related Questions