<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://www.w3.org/Bugs/Public/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4"
          urlbase="https://www.w3.org/Bugs/Public/"
          
          maintainer="sysbot+bugzilla@w3.org"
>

    <bug>
          <bug_id>30233</bug_id>
          
          <creation_ts>2018-03-21 16:14:40 +0000</creation_ts>
          <short_desc>[XSLT30] xsl:where-populated and interpretation of deemed-empty($item as item())</short_desc>
          <delta_ts>2018-03-21 16:54:24 +0000</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>XPath / XQuery / XSLT</product>
          <component>XSLT 3.0</component>
          <version>Recommendation</version>
          <rep_platform>PC</rep_platform>
          <op_sys>Windows NT</op_sys>
          <bug_status>NEW</bug_status>
          <resolution></resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Abel Braaksma">abel.online</reporter>
          <assigned_to name="Michael Kay">mike</assigned_to>
          
          
          <qa_contact name="Mailing list for public feedback on specs from XSL and XML Query WGs">public-qt-comments</qa_contact>

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>129100</commentid>
    <comment_count>0</comment_count>
    <who name="Abel Braaksma">abel.online</who>
    <bug_when>2018-03-21 16:14:40 +0000</bug_when>
    <thetext>Going over xsl:where-populated I found myself wondering what &quot;deemed-empty($item as item())&quot; means, in particular to &quot;as item()&quot;, which I think isn&apos;t specified.

I don&apos;t precisely recall the discussions. But &quot;as&quot; could be interpreted as &quot;cast as&quot; (even though casting to item() is not possible). It is not clear to me whether then the empty sequence or a sequence of more-than-one should raise an error (I think not, but the way it is currently written, one may conclude a type error should be raised).

Perhaps we could add something like this (assuming this is what was intended):

* if the seqtor evaluates to an empty sequence, or a sequence of more-than-one items, the sequence is returned as-is

* if the seqtor evaluates to a sequence of exactly one item, the result of evaluating deemed-empty($item) defines its behavior

Alternatively, an error could be raised, but that would make the following invalid (apart from the code being senseless, but in practice it is not inconceivable that something like this happens in practice):

&lt;xsl:where-populated&gt;
  &lt;a /&gt;
  &lt;b /&gt;
&lt;/xsl:where-populated&gt;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>129101</commentid>
    <comment_count>1</comment_count>
    <who name="Michael Kay">mike</who>
    <bug_when>2018-03-21 16:28:58 +0000</bug_when>
    <thetext>The phrase

where the function deemed-empty($item as item()) returns true if and only if $item is one of the following

is a slightly informal way of saying &quot;where deemed-empty is a function that takes an item as input and returns a boolean, which is true if and only if the item is one of the following&apos;.

The question of what deemed-empty does when given a non-singleton sequence doesn&apos;t arise because we never call it with anything other than a singleton item. Specifically, we only use it to evaluate the expression $R[not(deemed-empty(.))], where the argument is &quot;.&quot;, which is always a singleton.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>129102</commentid>
    <comment_count>2</comment_count>
    <who name="Michael Kay">mike</who>
    <bug_when>2018-03-21 16:39:03 +0000</bug_when>
    <thetext>In fact the function could probably be expanded to:

&lt;xsl:function name=&quot;deemed-empty&quot; as=&quot;xs:boolean&quot;&gt;
  &lt;xsl:param name=&quot;item&quot; as=&quot;item()&quot;/&gt;
  &lt;xsl:sequence select=&quot;


     ($item instance of document-node() and not($item/child::node())

     or

     ($item instance of element() and not($item/child::node()) 

     or

     ($item instance of node() and (not($item instance of document-node()) and not($item instance of element()) and string-length($item) gt 0)

     or

     ($item instance of xs:anyAtomicType and string($item)=&quot;&quot;)

     or 

     ($item instance of map(*) and map:size($item) eq 0)

     or

     ($item instance of array(*) and every $x in array:flatten($item) satisfies deemed-empty($x))

     &quot;/&gt;
&lt;/xsl:function&gt;

[except that &quot;and&quot; should have short-cut semantics for safety)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>129103</commentid>
    <comment_count>3</comment_count>
    <who name="Abel Braaksma">abel.online</who>
    <bug_when>2018-03-21 16:52:09 +0000</bug_when>
    <thetext>Oops, I think I misread the spec (again, sigh). 

The expression is &quot;$R[not(deemed-empty(.))]&quot; (where $R is the result of the seqtor). The function *signature* is &quot;deemed-empty($item as item())&quot;, it is not meant as a function *call*.

Given that, most of my bug report is moot.

This means that:

&lt;xsl:where-populated&gt;
  &lt;a /&gt;
  &lt;b /&gt;
&lt;/xsl:where-populated&gt;

would evaluate to the empty sequence, because neither &lt;a /&gt; nor &lt;/b&gt; has children and each item is evaluated with the focus on deemed-empty.

and

&lt;xsl:where-populated&gt;
  &lt;a /&gt;
  &lt;b&gt;&lt;x /&gt;&lt;/b&gt;
&lt;/xsl:where-populated&gt;

would evaluate to &lt;b&gt;&lt;x /&gt;&lt;/b&gt;, removing &lt;a /&gt; from the result sequence.

Still, perhaps we can clarify this in a note, for instance to be a little clearer about the function signature. Proposal:

* change the text to read &quot;...where the function deemed-empty has the signature deemed-empty($item as item()) as xs:boolean, which returns true if and only if $item is one of the following:&quot;

* add a line that says explicitly that each item is evaluated in turn, but that for streamability, the normal rules apply, that is, there is no implicit fork applied</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>129104</commentid>
    <comment_count>4</comment_count>
    <who name="Abel Braaksma">abel.online</who>
    <bug_when>2018-03-21 16:54:24 +0000</bug_when>
    <thetext>(looks like I was writing while you were writing the answer already, I think we were both arriving to the same conclusion)

Writing out the whole function is probably a good idea, it would make it clearer/more formal.</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>