<?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: mdh_node-predicates.xml 51709 2026-05-28 23:29:13Z syd $ -->
<TEI xmlns="http://www.wwp.northeastern.edu/ns/yaps" version="5.0">
  <teiHeader>
    <fileDesc>
      <titleStmt>
        <title>XPath node predicates</title>
        <author>Martin Holmes</author>
      </titleStmt>
      <editionStmt>
	<edition>Introduction to XSLT for Digital Humanities, Brown University, 08-10 March 2012</edition>
      </editionStmt>
      <publicationStmt>
        <distributor>Women Writers Project (via website)</distributor>
        <address>
          <addrLine>url:mailto:wwp@northeastern.edu</addrLine>
        </address>
        <date when="2012-06-04"/>
	<availability status="restricted">
	  <p>Copyright 2011 Martin D. Holmes 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>
      </publicationStmt>
      <sourceDesc>
	<p>Born digital</p>
      </sourceDesc>
    </fileDesc>
    <revisionDesc>
      <change when="2012-06-04" who="#mdh">Split instances where an example was immediately followed by its explanation so that the explanation can be elicited before being confirmed. Also fixed link to places file, and wrong answer to one of the questions.</change>
      <change when="2012-03-26" who="#sbauman.emt">added '#' to <att>who</att> values to match what was done in <name type="file">ham.xml</name>; changed an '=' to 'eq' for parallelism</change>
      <change when="2011-03-29" who="#sbauman.emt">Spruced up phrase-level encoding</change>
      <change when="2011-03-22" who="#mdh">Replaced old change element from another file with this one.</change> 
    </revisionDesc>
  </teiHeader>
  <text>
    <presentation>
      <section>
        <head>XPath Predicates</head>
        <slide>
          <list type="incremental">
            <item>You use paths and axes in XPath to arrive at specific nodes in your XML.</item>
            <item>You use predicates to further filter or test those nodes.</item>
            <item>Only nodes which satisfy the predicate will be selected.</item>
            <item>Predicates <emph>follow</emph> the step they apply to, and use <emph>square brackets</emph>.</item>
            <item><code>/TEI/text/body/div</code> means <q>all the
            <gi>div</gi> nodes which are children of
            <gi>body</gi></q>.
            </item>
            <item><code>/TEI/text/body/div[@type='chapter']</code> means
            <q>only those <gi>div</gi> nodes which are children of
            <gi>body</gi> <emph>and also have a type attribute
            with the value <val>chapter</val></emph></q>.</item>
          </list>
        </slide>
      </section>
      
      <section>
        <head>XPath Predicates: some examples</head>
        <slide>
          <list type="incremental">
            <item><eg><![CDATA[//div[head]]]></eg></item>
            <item> = all <gi>div</gi> nodes which have a direct child <gi>head</gi> element.</item>
            <item><eg><![CDATA[//div[contains(head,"Scene")]]]></eg></item>
            <item> = all <gi>div</gi> nodes which have a direct child <gi>head</gi> element which contains the text <q>Scene</q>.</item>
            <item><eg><![CDATA[//div[1]]]></eg></item>
            <item> = the first <gi>div</gi> node in the document.</item>
            <item><eg><![CDATA[//div[position() = last()]]]></eg></item>
            <item> = the last <gi>div</gi> node in the document.</item>
          </list>
        </slide>
      </section>
      
      <section>
        <head>XPath Predicates: Tasks (1)</head>
        <slide>
          <p>Using the <name type="file">places.xml</name> file here:<lb/><lb/>
            <ref target="http://www.wwp.northeastern.edu/outreach/seminars/uvic_xslt_2017/demos/xslt_intro/places.xml">http://www.wwp.northeastern.edu/outreach/seminars/uvic_xslt_2017/demos/xslt_intro/places.xml</ref><lb/><lb/>  
          and
          the XPath console in oXygen, find the following
          information:</p>
          <list type="incremental">
            <item>How many place entries are mapped as polygons? (Hint: a polygon location has more than 2 <gi>geo</gi> elements.)</item>
            <item>How many are single points?</item>
            <item>How many place entries contain external links (<tag>ref type="external"</tag>)?</item>
          </list>
        </slide>
      </section>
      
      <section>
        <head>XPath Predicates: Tasks (1) answers</head>
        <slide>
          <p>Using the <name type="file">places.xml</name> file, and
          the XPath console in oXygen, find the following
          information:</p>
          <list type="incremental">
            <item><label>Q:</label> How many place entries are mapped as polygons? (Hint: a polygon location has more than 2 <gi>geo</gi> elements.)</item>
            <item><label>A:</label> <eg><![CDATA[count(//place[count(location/geo) gt 2])]]></eg> (The answer is 77.)</item>
            <item><label>Q:</label> How many are single points?</item>
            <item><label>A:</label> <eg><![CDATA[count(//place[count(location/geo) eq 1])]]></eg> (The answer is 110.)</item>
            <item><label>Q:</label> How many place entries contain external links (<tag>ref type="external"</tag>)?</item>
            <item><label>A:</label> <eg><![CDATA[count(//place[descendant::ref[@type='external']])]]></eg> (The answer is 105.)</item>
          </list>
        </slide>
      </section>
      
      <section>
        <head>XPath Predicates can be chained</head>
        <slide>
          <list type="incremental">
            <item><eg><![CDATA[//div[contains(head, "Scene")][count(descendant::l) gt 200]]]></eg></item>
            <item> = all scenes containing more than 200 lines.</item>
            <item><eg><![CDATA[//div[contains(head, "Scene")][descendant::sp/@who='#Horatio']]]></eg></item>
            <item> = all scenes in which Horatio speaks.</item>
            <item><eg><![CDATA[//sp[position()=last()][@who='#Hamlet']]]></eg></item>
            <item> = speeches by Hamlet which are the last speeches in their scene.</item>
            <item>Supplementary question: how would you find the last speech in the whole play? Hint: you can use the <code>following::</code> axis.</item>
          </list>
        </slide>
        <lectureNote><p>The Hamlet file actually has lots of <gi>ab</gi> elements in speeches as well as <gi>l</gi> elements, so this line count stuff is not a true reflection of the length of speeches. It might be worth telling the students there's something wrong with it, and asking them to look at the XML source to see if they can figure out what it is. Then you could amend the first item in this slide, and some of the ones in the next slide, to account for this.</p></lectureNote>
        <tutorial><p>The Hamlet file actually has lots of <gi>ab</gi> elements in speeches as well as <gi>l</gi> elements, so this line count stuff is not a true reflection of the length of speeches. It might be worth telling the students there's something wrong with it, and asking them to look at the XML source to see if they can figure out what it is. Then you could amend the first item in this slide, and some of the ones in the next slide, to account for this.</p></tutorial>
      </section>
      
      <section>
        <head>XPath Predicates can be nested</head>
        <slide>
          <list type="incremental">
            <item><eg><![CDATA[//sp[descendant::l[contains(., "Ophelia")]]]]></eg></item>
            <item> = all speeches which contain metrical lines which mention Ophelia.</item>
            <item><eg><![CDATA[//div[contains(head, "Scene")][count(descendant::sp[@who = '#Hamlet']) gt 30]]]></eg></item>
            <item> = all scenes in which Hamlet has more than 30 speeches.</item>
            <item><eg><![CDATA[//sp[count(descendant::l[contains( .,"love")]) gt 2]]]></eg></item>
            <item> = speeches with three or more lines that mention "love".</item>
            <item><eg><![CDATA[//sp[count(l[contains( .,"love")]) gt 2]]]></eg> How does this differ from the XPath above? Under what circumstances would this difference matter?</item>
          </list>
        </slide>
      </section>
      
      <section>
        <head>XPath Predicates: Tasks (2)</head>
        <slide>
          <p>Using the <name type="file">places.xml</name> file, and
          the XPath console in &lt;oXygen/&gt;, find the following
          information:</p>
          <list type="incremental">
            <item>How many place entries which are single points contain external links?</item>
            <item>How many place entries mention the name whose <att>key</att> value is <val>kellett</val>?</item>
            <item>How many place entries have a bibliography with more than two items?</item>
          </list>
        </slide>
      </section>
      
      <section>
        <head>XPath Predicates: Tasks (2) answer 1</head>
        <slide>
          <list type="incremental">
            <item>How many place entries which are single points contain external links?</item>
            <item><eg><![CDATA[count(//place[descendant::ref[@type='external']][count(./location/geo) = 1])]]></eg> (The answer is 58.)</item>
          </list>
        </slide>
      </section>
      
      <section>
        <head>XPath Predicates: Tasks (2) answer 2</head>
        <slide>
          <list type="incremental">
            <item>How many place entries mention the name whose <att>key</att> value is <val>kellett</val>?</item>
            <item><eg><![CDATA[count(//place[descendant::name[@key='kellett']])]]></eg> (The answer is 9.)</item>
          </list>
        </slide>
      </section>
      
      <section>
        <head>XPath Predicates: Tasks (2) answer 3</head>
        <slide>
          <list type="incremental">
            <item>How many place entries have a bibliography with more than two items?</item>
            <item><eg><![CDATA[count(//place[count(descendant::bibl[parent::listBibl]) gt 2])]]></eg> (The answer is 12.)</item>
            <item>Note: if we omit the <code>[parent::listBibl]</code>
            predicate, we will be counting bibl elements which appear
            outside the bibliography list, in the body of the
            explanatory text.</item>
          </list>
        </slide>
      </section>
      
    </presentation>
  </text>
</TEI>
