<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="../../../_utils/schema/yaps.rnc" type="application/relax-ng-compact-syntax"?>
<?xml-model href="../../../_utils/schema/yaps.isosch" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<?xml-stylesheet type="text/xsl" href="yaps2slidy1.xslt"?>
<!-- $Id: conditionals.xml 51363 2026-03-27 17:51:50Z sconnell $ -->
<TEI xmlns="http://www.wwp.northeastern.edu/ns/yaps">
  <teiHeader>
    <fileDesc>
      <titleStmt>
        <title>Variables and Conditionals</title>
        <author>Syd Bauman</author>
        <author>David J. Birnbaum</author>
      </titleStmt>
      <editionStmt>
        <edition>Publishing TEI, Brown University, 10-12 December 2012</edition>
      </editionStmt>
      <publicationStmt>
        <distributor>Women Writers Project (via website)</distributor>
        <address>
          <addrLine>url:mailto:wwp@neu.edu</addrLine>
        </address>
        <date when="2013-11-21"/>
        <availability status="restricted">
          <p>Copyright 2012 Syd Bauman, David J. Birnbaum, and the Women Writers Project</p>
          <p>This TEI-encoded XML file is available under the terms of the <ref
              target="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons
              Attribution-ShareAlike 3.0 (Unported)</ref> license.</p>
        </availability>
        <pubPlace>Providence, RI USA</pubPlace>
      </publicationStmt>
      <sourceDesc>
        <p>Covers conditionals in XSLT 2.0</p>
      </sourceDesc>
    </fileDesc>
    <revisionDesc>
      <change when="2016-01-06" who="personography.xml#ksmith.awh">Added tutorial to 2nd xsl:if
        slide (created by Syd)</change>
      <change when="2016-01-04" who="personography.xml#sbauman.emt">
        <list>
          <item>Per e-mail conversation w/ Julia &amp; Kevin of 2015-12-16, rather than saying that
            XPath if-then-else is not covered, give a pointer to where it is covered; also fix the
            pointer in the tutorial</item>
          <item>Tweak tutorial language</item>
          <item>Add 2nd slide on <gi>xsl:if</gi></item>
        </list>
      </change>
      <change when="2016-01-04" who="personography.xml#ksmith.awh">Added tutorials on all
        slides</change>
      <change who="#sdb" when="2012-12-03">Created, based very heavily on
        https://svn.brown.edu/svn/stg/wwp/website/trunk/outreach/seminars/_current/presentations/xslt/djb_ten-functions.xml
        by David Birnbaum</change>
    </revisionDesc>
  </teiHeader>
  <text>
    <presentation>
      <abstract>
        <p>This tutorial, continuing the set of tutorials focused on XSLT, covers how to set up
          conditional statements for your transformations. This tutorial, through examples, explains
          the two conditional branching structures available in XSL: “if” and “choose.” For an
          additional branching structure using XPath, see: <ref target="../xslt/mdh_xsl_conditionals_tutorial_00.xhtml">XPath if-then-else</ref>.</p>
      </abstract>
      <section>
        <head>XSL variables</head>
        <slide>
          <list type="gloss" subtype="incremental">
            <label>useful</label>
            <item>shorthand reference</item>
            <label>to set</label>
            <item><code>&lt;xsl:variable name="<hi rend="class(interest)">whatever</hi>" select="<hi
                  rend="class(interest)">XPath</hi>"/&gt;</code>
              <!--	    <lb/>
	    <code>&lt;xsl:variable name="numPages" select="count( //pb )"/></code>
	    <lb/>
	    <code>&lt;xsl:variable name="title" select="/TEI/teiHeader/fileDesc/titleStmt/title[@type='main']"/></code>
-->
            </item>
            <label>to reference</label>
            <item><code>$whatever</code> (in an XPath, e.g. in a <att>select</att>)</item>
          </list>
          <p>Example <ref target="../../demos/publishing/personography-stats.xslt">without
              variables</ref>, and <ref
              target="../../demos/publishing/personography-stats-vars.xslt">with
            variables</ref>.</p>
        </slide>
        <tutorial>
          <p>Thus far (if you've been following the pre-defined primer structure), we have covered
            how to navigate the input document tree using simple XPath expressions to select
            particular elements and transform XML documents. Now we will see how to process and
            transform your input documents in more complex ways using conditional branching
            structures. Many of these examples will make use of XSL variables. This slide provides
            the syntax required to set and reference XSL variables within an XSL stylesheet.</p>
          <p>If you download and open the two pages in Oxygen (or open the examples in a browser and
            view the page source), you can see some of the benefits of using XSL variables.</p>
          <p>While both stylesheets are functionally the same, we can see the ease with which the
            number of authors, rulers, and people can be called upon and manipulated when using XSL
            variables. You might have a much longer XSL document that calls upon the same XPath
            expressions over and over again. If this is the case, you may want to use XSL variables.
            Another benefit to using XSL variables is that they can help other people working on the
            project read and understand your XSL stylesheets (provided you name your XSL variables
            intuitively).</p>
        </tutorial>
      </section>

      <section>
        <head>Conditionality and contingency</head>
        <slide>
          <p>
            <figure>
              <graphic url="../../../_utils/gfx/life-lessons-flowchart.png"/>
            </figure>
          </p>
        </slide>
        <lectureNote>
          <p>In general, XSLT templates are representations of contingency (when this node is
            matched, do this); our use of predicates in the previous examples demonstrates this.
            However, there are cases where it is inconvenient to use these kinds of tests: where we
            want instead to be able to say within a single template <q>when A, do a; when B, do
              b</q></p>
          <p>Examples: <list>
              <item>add an <q>s</q> if plural</item>
              <item>chop string down to length if it's too long</item>
              <item>add line number if it is divisible by 5</item>
              <item>use default for missing data</item>
            </list>
          </p>
        </lectureNote>
        <tutorial>
          <p>Generally, XSLT templates are representations of contingency; they essentially say
            "when this node is matched, do this." However, there are cases where these tests are not
            sufficient. Instead, we want to set up a set of conditions: <q>When A do a; when B, do
              b</q>, rather than simply matching one node to the other. It is usually inconvenient
            to do this simply through matching nodes, so we use <emph>conditionals</emph> to express
            what we want. Some examples of why you may want to use conditionals include, adding an
              <q>s</q> to something that is plural, adding a line number to every fifth line, or use
            a default for missing data.</p>
        </tutorial>
      </section>

      <section>
        <head>ifs, chooses, whens, and otherwises</head>
        <slide>
          <list type="incremental">
            <item>Almost all programming languages have <emph>conditional branching</emph>
              structures.</item>
            <item>XSLT has two: <tag>xsl:if</tag> and <tag>xsl:choose</tag>.</item>
            <item>XPath also has the <code>if-then-else</code> structure. (covered on <ref
                target="../xslt/mdh_xsl_conditionals_04.xhtml">this slide</ref>).</item>
          </list>
        </slide>
        <tutorial>
          <p>XSLT has two conditional branching structures. These are <gi>xsl:if</gi> and
              <gi>xsl:choose</gi>. These two structures will be covered in this tutorial.</p>
          <p>If you would like to learn about the XPath if-then-else structure (and there is no
          	reason why you shouldn't!), you can refer to these <ref target="../xslt/mdh_xsl_conditionals_tutorial_00.xhtml"
              >slides</ref>.</p>
        </tutorial>
      </section>

      <section>
        <head>Using <tag>xsl:if</tag></head>
        <slide>
          <p>A simple example: using <tag>xsl:if</tag> to pluralize <q>author</q> if there are
            multiple authors. <eg><![CDATA[<xsl:text>]]><hi style="font-weight:bold;">Author</hi><![CDATA[</xsl:text>
<]]><hi rend="css(color: blue;)">xsl:if </hi><![CDATA[ ]]><hi rend="css(color: red;)"
                >test=</hi><![CDATA["]]><hi rend="css(color: darkgreen;)">count( $docAuthors/author) gt 1</hi><![CDATA[">
  <xsl:text>]]><hi style="font-weight:bold;">s</hi><![CDATA[</xsl:text>
</]]><hi style="color:blue;">xsl:if</hi><![CDATA[>]]></eg></p>
          <list type="incremental">
            <item>Let's look at this in detail &#x2026;</item>
            <item>The <att>test</att> attribute contains an <emph>XPath expression</emph>:
                <code>count( $docAuthors/author ) gt 1</code>.</item>
            <item>The XPath expression starts by calling a function.
	    In particular, <code>count()</code>, which
              counts the number of items in its argument sequence. In this case, the argument to
                <code>count()</code> is the sequence of child <gi>author</gi> elements found in the
              variable <code>$docAuthors</code> (presumably the list of authors of the current
              document :-)</item>
            <item>The XPath expression then asks that the XSLT engine ask the question <q>is this
                (the value of the <code>count()</code> function) greater than one?</q>. That's what
              the <code>gt</code> means: <q>greater than</q>. (And similarly, <code>lt</code> is
                <q>less than</q>, <code>eq</code> is <q>equal to</q>, and <code>ne</code> is <q>not
                equal to</q>.) You could use <code>></code> instead, but a) using pointy-brackets
              inside an attribute is fraught with danger, and b) the <code>></code>,
                <code>&lt;</code>, <code>=</code>, and <code>!=</code> operators are actually for
              something somewhat more complex: comparison of sequences.</item>
            <item>The answer to that question (<q>is this (the value of the <code>count()</code>
                function) greater than one?</q>) is either <code>true()</code> or
                <code>false()</code>.</item>
            <item>The content of the <tag>xsl:if</tag> element is executed if and only if the
                <att>test</att> attribute evaluates to <code>true()</code>.</item>
          </list>
        </slide>
        <tutorial>
          <p>The example in this slide uses <gi>xsl:if</gi> to pluralize the word "author" if there
            is more than one listed.
            <!-- The
          <att>test</att> attribute on <gi>xsl:if</gi> asks the XSLT
          processor to count the number of <gi>author</gi> elements
          within <gi>docAuthor</gi>, and then to compare that number
          to one. If the number is greater than one, the text
          <q>s</q> is added after the text <q>Author</q>.</p>
          <p>Every <att>test</att> attribute contains an XPath
          expression. -->
            The slide explains in detail how this particular <gi>xsl:if</gi> is evaluated.</p>
          <p>In general, every <att>test</att> attribute will contain an XPath expression. The
            expression either evaluates as true or as false. If it is true, then the content of
              <gi>xsl:if</gi> is applied. If it is false, nothing is done. </p>
          <p>In this example, the content of <gi>xsl:if</gi> is a simple text node, but we can
            imagine more complex examples like checking if there is an <att>ref</att> on
              <gi>persName</gi>, and if there is, then proceeding with a whole additional snippet of
            code.</p>
        </tutorial>
      </section>

      <section>
        <head>Using <tag>xsl:choose</tag></head>
        <slide>
          <p>But what if you want to do something else if the test evaluates to
            <code>false()</code>?</p>
          <p>Or what if it isn't a simple true/false problem?</p>
          <eg><![CDATA[<div>      
  <head>WWP Dress Code</head>
  <p>
    <]]><hi rend="css(color: maroon;)">xsl:choose</hi><![CDATA[>
      <]]><hi rend="css(color: blue;)">xsl:when </hi><![CDATA[ ]]><hi rend="css(color: red;)"
            >test=</hi><![CDATA["]]><hi rend="css(color: darkgreen;)">$surname eq 'Flanders'</hi><![CDATA[">
        <xsl:text>no penguin tie</xsl:text>
      </]]><hi rend="css(color: blue;)">xsl:when</hi><![CDATA[>
      <]]><hi rend="css(color: blue;)">xsl:when </hi><![CDATA[ ]]><hi rend="css(color: red;)"
            >test=</hi><![CDATA["]]><hi rend="css(color: darkgreen;)">$surname eq 'Bauman'</hi><![CDATA[">
        <xsl:text>penguin tie</xsl:text>
      </]]><hi rend="css(color: blue;)">xsl:when</hi><![CDATA[>
      <]]><hi rend="css(color: blue;)">xsl:otherwise</hi><![CDATA[>
        <xsl:text>unpredictable</xsl:text>
      </]]><hi rend="css(color: blue;)">xsl:otherwise</hi><![CDATA[>
    </]]><hi rend="css(color: maroon;)">xsl:choose</hi><![CDATA[>
  </p>
</div>]]></eg>
          <list>
            <item>The processor looks at each <tag>xsl:when</tag> in turn; when it finds one whose
                <att>test</att> evaluates to <code>true()</code>, it processes that one, and then
              exits the <tag>xsl:choose</tag>.</item>
            <item>If none are true, it processes <tag>xsl:otherwise</tag> (assuming there is
              one).</item>
          </list>
        </slide>
        <tutorial>
          <p>The <gi>xsl:if</gi> element works well if you only want to apply constructors (i.e., do
            things) when a simple test proves to be true (or false, as you can always reverse the
            logic of a test by wrapping it in a <code>not()</code> function), and don't want to do
            anything if said simple test proves to be false (or true). But there may be instances in
            which you want to do something when the test evaluates as true, and something else when
            it evaluates as false. Indeed, you may want to apply rules to things that aren't even
            simple true/false statements.</p>
          <p>In these cases, you will want to use <gi>xsl:choose</gi>, which allows you to specify
            rules for several different scenarios. The children of <gi>xsl:choose</gi> are one or
            more <gi>xsl:when</gi> statements followed by zero or one <gi>xsl:otherwise</gi>
            statement.</p>
          <p>The processor evaluates the <att>test</att> attribute of each <gi>xsl:when</gi> in
            order. If the XPath expression is false, the processor goes to the next
              <gi>xsl:when</gi>. When the processor finds that the <att>test</att> of an
              <gi>xsl:when</gi> is true, it performs the content of that <gi>xsl:when</gi>,
              <emph>and stops looking</emph> at the rest of the <gi>xsl:when</gi> elements and the
              <gi>xsl:otherwise</gi> (if there even is one).</p>
          <p>If none of the <att>test</att> attributes for <gi>xsl:when</gi> are true, then the
            processor will execute the content of the <gi>xsl:otherwise</gi> (if there is one).</p>
          <p>Thus at most <emph>one</emph> child of an <gi>xsl:choose</gi> is executed. If there is
            no <gi>xsl:otherwise</gi> child of the <gi>xsl:choose</gi>, it is possible that
              <emph>no</emph> child of the <gi>xsl:choose</gi> will be executed.</p>
        </tutorial>
      </section>

      <section>
        <head>More than one way &#x2026;</head>
        <slide>
          <p>The following two examples do the same thing: indent all but the first output paragraph
            in a division.</p>
          <eg><![CDATA[<xsl:template match="div/p">
  <p>
    <xsl:if test="preceding-sibling::p">
      <xsl:attribute name="style" select="'text-indent: 1em;'"/>
    </xsl:if>
    <xsl:apply-templates/>
  </p>
</xsl:template>]]></eg>
          <eg><![CDATA[<xsl:template match="div/p">
  <p><xsl:apply-templates/></p>
</xsl:template>
<xsl:template match="div/p[preceding-sibling::p]">
  <p style="text-indent: 1em;">
    <xsl:apply-templates/>
  </p>
</xsl:template>]]></eg>
        </slide>
        <lectureNote>
          <p>Each example accomplishes the same thing. Whether you use one or the other is a matter
            of preference or convenience. It is possible that one is faster than the other using a
            particular XSLT engine; but the other might be faster than the one using a different
            XSLT engine. And the difference is probably infinitesmal, anyway.</p>
        </lectureNote>
        <tutorial>
          <p>Most situations you encounter will have more than one way to process your documents in
            the ways that you want. Here, each example accomplishes the same thing. Whether you use
            one or the other is a matter of preference or convenience. It is possible that one is
            faster than the other using a particular XSLT engine; but the other might be faster than
            the one using a different XSLT engine. And the difference is probably infinitesmal,
            anyway.</p>
          <p>The <ref target="../xslt/mdh_xsl_conditionals_tutorial_00.xhtml">XPath if-then-else tutorial</ref> includes some exercise files with which you can
            practice using conditional brancing structures. It is also the next tutorial in the primer sequence.</p>
          <list>
            <head>This tutorial is complete, please see links below to continue:</head>
            <item><ref target="../xslt/mdh_xsl_conditionals_tutorial_00.xhtml">Proceed to next
                tutorial in Transformation and Publication Primer</ref></item>
            <item><ref target="../../../../resources/transformation.html">Return to Transformation
                and Publication Primer</ref></item>
            <item><ref target="../../../../resources/tutorial_main.html">Return to main tutorial
                page</ref></item>
          </list>
        </tutorial>
      </section>

    </presentation>
  </text>
</TEI>
