Bug #6333


Representing empty sequence

Added by O'Neil Delpratt 6 months ago. Updated 15 days ago.

In Progress
Saxon-C Internals
Start date:
Due date:
% Done:


Estimated time:
Applies to branch:
Fix Committed on Branch:
Fixed in Maintenance Release:
Found in version:
Fixed in version:
SaxonC Languages:
SaxonC Platforms:
SaxonC Architecture:


SaxonC currently does not properly represent empty sequences via the API. What we need is an XdmEmptySequence class similar to its Java counterpart. Moreover, In SaxonJ (Java) an empty XdmValue is also an empty sequence which can be passed as a parameter to an expression of stylesheet, but this fails in SaxonC.

For example:

    xp = saxonproc.new_xpath_processor()
    xp.declare_namespace("fn", "")
    xdm_value = PyXdmValue()
    xp.set_parameter('p', xdm_value)
    assert xp.effective_boolean_value("fn:empty($p)")

Crashes out with the following exception:

java.lang.IllegalArgumentException: Invalid handle
    at net.sf.saxon.option.cpp.ProcessorDataAccumulator.addProcessorDataPair(

This is probably because the empty PyXdmValue() object is not internally getting converted to an empty sequence.

Related issues

Related to SaxonC - Bug #6327: TypeError: __str__ returned non-string (type NoneType)ClosedO'Neil Delpratt2024-01-192024-01-19

Actions #1

Updated by O'Neil Delpratt 6 months ago

The example result = xp.evaluate_single("(1,2,3)[10]") in SaxonC Python currently returns None because the result is an empty sequence. In Java this would be XdmEmptySequence.

Actions #2

Updated by O'Neil Delpratt 6 months ago

  • Related to Bug #6327: TypeError: __str__ returned non-string (type NoneType) added
Actions #3

Updated by O'Neil Delpratt 6 months ago

  • Status changed from New to In Progress

Committed a partial fix to solve the Invalid handle error. We now handle the empty PyXdmValue() as an empty sequence.

Actions #4

Updated by O'Neil Delpratt 16 days ago

This partial fix was applied in the SaxonC 12.5 maintenance release.

Actions #5

Updated by O'Neil Delpratt 16 days ago

  • Applies to branch 12 added
  • SaxonC Languages All added
  • SaxonC Platforms All added

Reported by user:

"Ideas for better pythonic behaviour in SaxonC. As an example, the evaluate() function of the XPath processor

returns an PyXdmValue instance. But it can also return None (not documented) which isn’t so “pythonic” but more of a C/C++ result. Ideally, the function would always return a PyXdmValue

which, as per docs, can indeed be an empty sequence. In Python, the common pattern is something like

   for text_node in xpath_proc.evaluate("//*/text()"):  # Might return an empty sequence, thus no iteration.

As it stands, I always have to check for None results:

   xdm_value = xpath_proc.evaluate("//*/text()”)
   if xdm_value:
       for text_node in xdm_value:

or similar, harder-to-read and non-pythonic patterns."

Actions #6

Updated by O'Neil Delpratt 16 days ago

I agree with the user and thought it would be useful to add the feedback here in this bug issue. I think we could easily change the Python extension to return XdmValue() for the empty/None case and it would make things work for the iteration example. We will discuss if the XdmEmptySequence class should be introduced in 12.6 or the 13 release.

Actions #7

Updated by Jens Troeger 15 days ago

Thank you for adding note #5 above!

In that context I have one question: what’s the difference between an empty XdmValue and an XdmEmptySequence, how are they related to each other? I found this C# blurb which indicates that the XdmEmptySequence is a subclass for empty XdmValues. Would that carry over to Python (and other languages)?

Actions #8

Updated by Michael Kay 15 days ago

In that context I have one question: what’s the difference between an empty XdmValue and an XdmEmptySequence,

In the Java (s9api) model, these are alternative Java representations of the same XDM value (namely the empty sequence).

In many APIs we endeavour to ensure that the returned XdmValue is normalized, for example a singleton node will always be returned as an XdmNode and an empty sequence will always be returned as an XdmEmptySequence; but that isn't always guaranteed. It's best to think of XdmEmptySequence as a convenience class for constructing an empty sequence, it is certainly not the case that every XdmValue that represents an empty sequence will be implemented as an instance of XdmEmptySequence.

Please register to edit this issue

Also available in: Atom PDF