bugfixing 1, NULLs

In the previous entry I mentioned three bugs to be fixed. In this post I describe the second issue.

To remind:

The second issue is definitely not a bug, but it still worth checking. Is it possible to create comment or PI with NULL (not empty string!) content using SXML to XML conversion?

The first attempt was to use the following stylesheet:

<x:variable name="xx">
  <s:scheme>
    '(E (*PI* mypi))
  </s:scheme>
</x:variable>
<x:for-each select="e:node-set($xx)" xmlns:e="http://exslt.org/common">
  <w>
    <s:scheme>
      (define x (x:current-node))
      (display "From nodeset: ")
      (display x)
      (newline)
    </s:scheme>
  </w>
</x:for-each>

Variable "xx" is created by conversion from SXML "(E (*PI* mypi))" to XML. A correspsoniding PI node has a NULL content. At the moment, the only way to execute XML to SXML conversion is to use the function "x:current-node" which returns the context node. I make "xx" the context node by using "for-each" and "node-set".

I tested the stylesheet and got the correct answer:

(*TOP* (E (*PI* mypi)))

I was surprised because I hardly believed that this correct answer was produced by a weak C code. After some printf-testing I made sure that actually C code wasn't executing at all.

How could it happen?

If you have been reading my notes for a some time, you know the answer.

Yes, it's the internal map between SXML and XML nodes. While creating the variable "xx", a new pair was added to the map. While starting for-each, the context node was found in the map, so the corresponding SXML was returned immediately without any conversion.

I modified the stylesheet a bit. Note that we make a copy of xx's XML and assign it to the variable "yy". Then we make for-each over "yy" that is not in the map.

<x:variable name="xx">
  <s:scheme>
    '(E (*PI* mypi))
  </s:scheme>
</x:variable>
<x:variable name="yy">
  <x:copy-of select="$xx"/>
</x:variable>
<x:for-each select="e:node-set($yy)" xmlns:e="http://exslt.org/common">
  <w>
    <s:scheme>
      (define x (x:current-node))
      (display "From nodeset: ")
      (display x)
      (newline)
    </s:scheme>
  </w>
</x:for-each>

After running the modified stylesheet I got the incorrect answer:

(*TOP* (E (*PI* mypi #f)))

"#f" shouldn't present here.

So, the answer on the question is: yes, it's possible to create NULL content. More, in XML to SXML conversion we handled NULLs incorrectly.

Now this feature is fixed and conversion gives the correct result again:

(*TOP* (E (*PI* mypi)))

Categories: Generative XML

Updated: