<?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>9722</bug_id>
          
          <creation_ts>2010-05-12 20:08:37 +0000</creation_ts>
          <short_desc>[XSLT 2.1] Enhancement to conditional modes</short_desc>
          <delta_ts>2014-05-15 14:00:20 +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>Working drafts</version>
          <rep_platform>PC</rep_platform>
          <op_sys>All</op_sys>
          <bug_status>CLOSED</bug_status>
          <resolution>WONTFIX</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="Evan Lenz">evan</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>35650</commentid>
    <comment_count>0</comment_count>
    <who name="Evan Lenz">evan</who>
    <bug_when>2010-05-12 20:08:37 +0000</bug_when>
    <thetext>I like being able to set mode=&quot;#current&quot;. It allows me to set the mode conditionally, based on the current mode. But I have repeatedly come across the situation where I want to make the mode conditional (dependent on current) but not be the *same as* current. In other words, I want to dispatch to a different mode depending on what the current mode is. I can think of several ways of designing this into the language (without allowing mode names to be dynamic or directly accessible as values).

Let me know your thoughts on this. I have both specific use cases and design ideas, but this is the essence of what I want.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>35651</commentid>
    <comment_count>1</comment_count>
    <who name="Michael Kay">mike</who>
    <bug_when>2010-05-12 20:35:19 +0000</bug_when>
    <thetext>We provide accessor functions for most components of the dynamic context, and I can&apos;t immediately see a good reason why we shouldn&apos;t provide current-mode().

Allowing the mode attribute on apply-templates to be set dynamically is something that requires more careful thought. A particular difficulty is that we want to know statically whether the apply-templates uses a streaming or non-streaming mode.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>35652</commentid>
    <comment_count>2</comment_count>
    <who name="Michael Kay">mike</who>
    <bug_when>2010-05-12 20:35:19 +0000</bug_when>
    <thetext>We provide accessor functions for most components of the dynamic context, and I can&apos;t immediately see a good reason why we shouldn&apos;t provide current-mode().

Allowing the mode attribute on apply-templates to be set dynamically is something that requires more careful thought. A particular difficulty is that we want to know statically whether the apply-templates uses a streaming or non-streaming mode.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>35653</commentid>
    <comment_count>3</comment_count>
    <who name="Evan Lenz">evan</who>
    <bug_when>2010-05-12 21:44:28 +0000</bug_when>
    <thetext>Dynamic access to mode names would give me a really ugly way to do what I want... (see Example #2 below). But I think it would be so painful as to defeat the purpose for me (especially since I can already pass a &quot;mode name&quot; via a tunnel parameter at the original point of invocation).

What I&apos;d really like to do is refer to the *previous* mode, both in apply-templates and in match patterns.

So &lt;xsl:apply-templates/&gt; would now allow mode=&quot;#previous&quot;

And &lt;xsl:template&gt; would now allow mode=&quot;myPreviousMode/myCurrentMode&quot; - limited to one separator (&quot;/&quot; as here or some other non-space, non-QName character).

Thus every invocation of apply-templates is conceptually a conditional mode invocation, parameterized by the current mode at the point of invocation. I can think of several ways of modeling this (e.g., a mode can actually be a *pair* of QNames, depending on whether its previous mode is ever referenced in the stylesheet).



EXAMPLE #1 (with access to previous mode):

&lt;!-- In stage 1, delete &lt;foo&gt;&apos;s content --&gt;
&lt;xsl:template mode=&quot;stage1/content&quot; match=&quot;foo&quot;/&gt;

&lt;!-- In stage 3, add &lt;bar/&gt; after &lt;bat/&gt; --&gt;
&lt;xsl:template mode=&quot;stage3/after&quot; match=&quot;bat&quot;&gt;
  &lt;bar/&gt;
&lt;/xsl:template&gt;


&lt;!-- The boilerplate code that enables me to write the above surgically precise rules --&gt;
&lt;!-- By default, copy everything unchanged --&gt;
&lt;xsl:template mode=&quot;stage1
                    stage2
                    stage3&quot; match=&quot;*&quot;&gt;
  &lt;xsl:apply-templates mode=&quot;before&quot; select=&quot;.&quot;/&gt;
  &lt;xsl:copy&gt;
    &lt;xsl:apply-templates mode=&quot;#current&quot; select=&quot;@*&quot;/&gt;
    &lt;xsl:apply-templates mode=&quot;content&quot; select=&quot;.&quot;/&gt;
  &lt;/xsl:copy&gt;
  &lt;xsl:apply-templates mode=&quot;after&quot; select=&quot;.&quot;/&gt;
&lt;/xsl:template&gt;

&lt;!-- By default, process children --&gt;
&lt;xsl:template mode=&quot;content&quot; match=&quot;*&quot;&gt;
  &lt;xsl:apply-templates mode=&quot;#previous&quot;/&gt;
  &lt;!-- Processor knows statically that this will be either &quot;stage1&quot;, &quot;stage2&quot;, or &quot;stage3&quot; --&gt;
&lt;/xsl:template&gt;

&lt;!-- By default, don&apos;t add anything before or after --&gt;
&lt;xsl:template mode=&quot;before
                    after&quot; match=&quot;*&quot;/&gt;



EXAMPLE #2 (achieving the same, using only current-mode()):

&lt;!-- In stage 1, delete &lt;foo&gt;&apos;s content --&gt;
&lt;xsl:template mode=&quot;stage1-content&quot; match=&quot;foo&quot;/&gt;

&lt;!-- In stage 3, add &lt;bar/&gt; after &lt;bat/&gt; --&gt;
&lt;xsl:template mode=&quot;stage3-after&quot; match=&quot;bat&quot;&gt;
  &lt;bar/&gt;
&lt;/xsl:template&gt;


&lt;!-- The boilerplate code that enables me to write the above surgically precise rules --&gt;
&lt;!-- By default, copy everything unchanged --&gt;
&lt;xsl:template mode=&quot;stage1
                    stage2
                    stage3&quot; match=&quot;*&quot;&gt;
  &lt;xsl:variable name=&quot;stage1&quot; select=&quot;current-mode() eq &apos;stage1&apos;&quot;/&gt;
  &lt;xsl:variable name=&quot;stage2&quot; select=&quot;current-mode() eq &apos;stage2&apos;&quot;/&gt;
  &lt;xsl:choose&gt;
    &lt;xsl:when test=&quot;$stage1&quot;&gt;
      &lt;xsl:apply-templates mode=&quot;stage1-before&quot; select=&quot;.&quot;/&gt;
    &lt;/xsl:when&gt;
    &lt;xsl:when test=&quot;$stage2&quot;&gt;
      &lt;xsl:apply-templates mode=&quot;stage2-before&quot; select=&quot;.&quot;/&gt;
    &lt;/xsl:when&gt;
    &lt;xsl:otherwise&gt;
      &lt;xsl:apply-templates mode=&quot;stage3-before&quot; select=&quot;.&quot;/&gt;
    &lt;/xsl:otherwise&gt;
  &lt;/xsl:choose&gt;
  &lt;xsl:copy&gt;
    &lt;xsl:apply-templates mode=&quot;#current&quot; select=&quot;@*&quot;/&gt;
    &lt;xsl:choose&gt;
      &lt;xsl:when test=&quot;$stage1&quot;&gt;
        &lt;xsl:apply-templates mode=&quot;stage1-content&quot; select=&quot;.&quot;/&gt;
      &lt;/xsl:when&gt;
      &lt;xsl:when test=&quot;$stage2&quot;&gt;
        &lt;xsl:apply-templates mode=&quot;stage2-content&quot; select=&quot;.&quot;/&gt;
      &lt;/xsl:when&gt;
      &lt;xsl:otherwise&gt;
        &lt;xsl:apply-templates mode=&quot;stage3-content&quot; select=&quot;.&quot;/&gt;
      &lt;/xsl:otherwise&gt;
    &lt;/xsl:choose&gt;
  &lt;/xsl:copy&gt;
  &lt;xsl:choose&gt;
    &lt;xsl:when test=&quot;$stage1&quot;&gt;
      &lt;xsl:apply-templates mode=&quot;stage1-after&quot; select=&quot;.&quot;/&gt;
    &lt;/xsl:when&gt;
    &lt;xsl:when test=&quot;$stage2&quot;&gt;
      &lt;xsl:apply-templates mode=&quot;stage2-after&quot; select=&quot;.&quot;/&gt;
    &lt;/xsl:when&gt;
    &lt;xsl:otherwise&gt;
      &lt;xsl:apply-templates mode=&quot;stage3-after&quot; select=&quot;.&quot;/&gt;
    &lt;/xsl:otherwise&gt;
  &lt;/xsl:choose&gt;
&lt;/xsl:template&gt;

&lt;!-- By default, process children --&gt;
&lt;xsl:template mode=&quot;stage1-content
                    stage2-content
                    stage3-content&quot; match=&quot;*&quot;&gt;
  &lt;xsl:choose&gt;
    &lt;xsl:when test=&quot;current-mode() eq &apos;stage1-content&apos;&quot;&gt;
      &lt;xsl:apply-templates mode=&quot;stage1&quot;/&gt;
    &lt;/xsl:when&gt;
    &lt;xsl:when test=&quot;current-mode() eq &apos;stage2-content&apos;&quot;&gt;
      &lt;xsl:apply-templates mode=&quot;stage2&quot;/&gt;
    &lt;/xsl:when&gt;
    &lt;xsl:otherwise&gt;
      &lt;xsl:apply-templates mode=&quot;stage3&quot;/&gt;
    &lt;/xsl:otherwise&gt;
  &lt;/xsl:choose&gt;
&lt;/xsl:template&gt;

&lt;!-- By default, don&apos;t add anything before or after --&gt;
&lt;xsl:template mode=&quot;stage1-before
                    stage2-before
                    stage3-before
                    stage1-after
                    stage2-after
                    stage3-after&quot; match=&quot;*&quot;/&gt;


Another way to look at this is that I want my XSLT processor to do the work of automatically translating Example #1 into Example #2 for me, just as it already does with mode=&quot;#current&quot;.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>35655</commentid>
    <comment_count>4</comment_count>
    <who name="Evan Lenz">evan</who>
    <bug_when>2010-05-12 22:05:20 +0000</bug_when>
    <thetext>A couple of additional thoughts:

&quot;/&quot; as the separator would probably be confusing. &quot;&gt;&quot; might be nicer.

For streaming vs. non-streaming, I think you already need to solve this problem with mode=&quot;#current&quot;, right? mode=&quot;#previous&quot; is technically no more dynamic than mode=&quot;#current&quot;. (It resolves to a statically determined, finite list of possibilities.)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>36964</commentid>
    <comment_count>5</comment_count>
    <who name="Michael Kay">mike</who>
    <bug_when>2010-07-16 15:35:11 +0000</bug_when>
    <thetext>Thanks for the input, Evan. We looked at it carefully and felt that given the complexity involved, the requirements this meets are rather specialized.</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>