Úspěšně vyřešená cvičení na XPATH

Z interaktivního tutorialu http://learn.onion.net/language=en/35426/w3c-xpath. Pozor, interaktivní verze obsahuje cennou nápovědu. Zadání je tady okopírované jenom kvůli lepší navigaci. Chybí předposlední 4 cvičení, poslední tam už zase je.

Celkem dobré výkladové slajdy jsou taky tady (vznikly zcela nezávisle na interaktivním tutorialu na onion.net): http://www.tei-c.org/Talks/OUCS/2006-02/talk-xpath.pdf. Výhodou je, že se XPATH vysvětluje přímo na dokumentech uspořádaných podle TEI.

Attribute selection

  Source document
  <document name="getit Übungsaufgaben" />
  Challenge
  
  Output the content of the attribute “name”.
  Desired selection (text output)
  getit Übungsaufgaben
  Exercise
  Your input
  //@name

Conditional element selection

  Task
  Source document
  <document xmlns:xlink="http://www.w3.org/1999/xlink">
    <linkList name="A">
      <document xlink:href="15024" />
      <document xlink:href="15028" />
    </linkList>
    <linkList name="B">
      <document xlink:href="15030" />
      <document xlink:href="15032" />
    </linkList>
  </document>
  Challenge
  
  Select all document elements below the node “linkList” with the name A.
  Desired selection (XML-output)
  
      <document xlink:href="15024" xmlns:xlink="http://www.w3.org/1999/xlink" />
  
      <document xlink:href="15028" xmlns:xlink="http://www.w3.org/1999/xlink" />
  
  Exercise
  Your input
  
  //linkList[@name = 'A']/*

Pozor, důležitý je ten požadavek na jakýkoli uzel jako potomek. Jinak se najde jejich rodič a oni v něm, ale to nebylo zadání úlohy.

Merging character strings

Source document
    
    <person>
      <lastName>Peter</lastName>
      <firstName>Hans</firstName>
    </person>
    
    Challenge
    
    Create an output consisting of the elements “lastName”, the character string ", " and firstName.
    Desired selection (text output)
    Peter, Hans
    Exercise
    
    concat(//lastName, ', ' , //firstName)

Filtering by attribute value

Task
Source document
<jobs>
<job priority="critical" name="Müll rausbringen" />
    <job priority="low" name="Möbel säubern" />
    <job priority="low" name="Teppich reinigen" />
    <job priority="medium" name="Fenster putzen" />
    <job priority="high" name="Pflanzen gießen" />
  </jobs>
  Challenge
  
  Select all jobs with a priority corresponding to the value “critical” or “high”.
  Desired selection (XML-output)
  
      <job priority="critical" name="Müll rausbringen" />
  
      <job priority="high" name="Pflanzen gießen" />
  
  Exercise
  Your input
  
  //job[@priority='critical' or @priority='high']

Filtering by numeric values

  Task
  Source document
  <persons>
    <person firstName="Hans" lastName="Mustermann" age="28" />
    <person firstName="Herbert" lastName="Möllemann" age="33" />
    <person firstName="Peter" lastName="Meier" age="37" />
    <person firstName="Ulrike" lastName="Albrecht" age="45" />
  </persons>
  Challenge
  
  Select all persons aged less than 35 years.
  Desired selection (XML-output)
  
      <person firstName="Hans" lastName="Mustermann" age="28" />
  
      <person firstName="Herbert" lastName="Möllemann" age="33" />
  
  Exercise
  Your input
  //person[@age < 35]

Limiting number

  Task
  Source document
  <persons>
    <person firstName="Hans" lastName="Mustermann" age="28" />
    <person firstName="Herbert" lastName="Möllemann" age="33" />
    <person firstName="Peter" lastName="Meier" age="37" />
    <person firstName="Ulrike" lastName="Albrecht" age="45" />
  </persons>
  Challenge
  
  Select the first three person elements.
  Desired selection (XML-output)
  
      <person firstName="Hans" lastName="Mustermann" age="28" />
  
      <person firstName="Herbert" lastName="Möllemann" age="33" />
  
      <person firstName="Peter" lastName="Meier" age="37" />
  
  Exercise
  Your input
  //person[position() < 4]
  //person[position() = 1 or position() = 2 or position() = 3]

Filtering by character conditions

  Task
  Source document
  <persons>
    <person firstName="Hans" lastName="Mustermann" age="28" />
    <person firstName="Herbert" lastName="Möllemann" age="33" />
    <person firstName="Peter" lastName="Meier" age="37" />
    <person firstName="Ulrike" lastName="Albrecht" age="45" />
  </persons>
  Challenge
  
  Select all persons whose first name begins with the letter H.
  Desired selection (XML-output)
  
      <person firstName="Hans" lastName="Mustermann" age="28" />
  
      <person firstName="Herbert" lastName="Möllemann" age="33" />
  
  Exercise
  Your input
  //person[starts-with(@firstName, 'H')]

Filtering by text length

        Task
        Source document
        <persons>
          <person firstName="Hans" lastName="Mustermann" age="28" />
          <person firstName="Herbert" lastName="Möllemann" age="33" />
          <person firstName="Peter" lastName="Meier" age="37" />
          <person firstName="Ulrike" lastName="Albrecht" age="45" />
          <person firstName="Uwe" lastName="Peters" age="34" />
        </persons>
        Challenge
        
        Select all person elements with an attribute “firstName” a maximum of 5 characters long.
        Desired selection (XML-output)
        
            <person firstName="Hans" lastName="Mustermann" age="28" />
        
            <person firstName="Peter" lastName="Meier" age="37" />
        
            <person firstName="Uwe" lastName="Peters" age="34" />
        
        Exercise
        
        //person[string-length(@firstName) < 6]
        
        
        Rounding up and down and adding
        Task
        Source document
        <numbers>
          <number>33</number>
          <number>34.4</number>
          <number>33.8</number>
          <number>33.43</number>
          <number>34.46</number>
          <number>35</number>
          <number>33.49</number>
          <number>33.00</number>
        </numbers>
        Challenge
        
        Determine the sum of all numbers, which round off to 34.
        Desired selection (text output)
        102,66
        Exercise
        Your input
        sum(//numbers/*[round(.) = 34])
        sum(//numbers/number[round(.) = 34])
        Congratulations!
        
        You solved this exercise.
        Your result
        102,66

Selecting the following siblings

  Task
  Source document
  
  Your are at the green marked position
  <products>
    <product id="1" name="Teekanne" price="25.00" category="1" />
    <product id="2" name="Bleistift" price="0.29" category="2" />
    <product id="3" name="Lautsprecher" price="19.00" category="2" />
    <product id="4" name="Tasse" price="1.99" category="1" />
    <product id="5" name="Apfelsaft" price="1.49" category="1" />
    <product id="6" name="CD-Rohling" price="0.89" category="2" />
    <category id="1" name="Sortiment 2005" />
    <category id="2" name="Sortiment 2006" />
  </products>
  Challenge
  
  Select the following product-siblings relatively from their current node.
  Desired selection (XML-output)
  
      <product id="4" name="Tasse" price="1.99" category="1" />
  
      <product id="5" name="Apfelsaft" price="1.49" category="1" />
  
      <product id="6" name="CD-Rohling" price="0.89" category="2" />
  
  Exercise
  Your input
  //product[@name="Lautsprecher"]/following-sibling::product

Selecting following siblings with filtering

  Task
  Source document
  
  Your are at the green marked position
  <products>
    <product id="1" name="Teekanne" price="25.00" category="1" />
    <product id="2" name="Bleistift" price="0.29" category="2" />
    <product id="3" name="Lautsprecher" price="19.00" category="2" />
    <product id="4" name="Tasse" price="1.99" category="1" />
    <product id="5" name="Apfelsaft" price="1.49" category="1" />
    <product id="6" name="CD-Rohling" price="0.89" category="2" />
    <category id="1" name="Sortiment 2005" />
    <category id="2" name="Sortiment 2006" />
  </products>
  Challenge
  
  Select the following product siblings, which contain the value 1 as a category, relatively from their current node.
  Desired selection (XML-output)
  
      <product id="4" name="Tasse" price="1.99" category="1" />
  
      <product id="5" name="Apfelsaft" price="1.49" category="1" />
  
  Exercise
  Your input

//product[@name="Lautsprecher"]/following-sibling::product[@category="1"]

Attribute selection with namespaces

Task Source document Challenge

Select the value of the attribute “href”, which is connected to the namespace “http://www.w3.org/1999/xlink”. For your XPath expression, this namespace is attached to the prefix x. Desired selection (text output) http://www.google.de/ Available prefix for the XPath-expression prefix Namespace x http://www.w3.org/1999/xlink Exercise Your input Your result //@x:href

Selecting elements by name

    Task
    Source document
    <document>
      <item_0001>Erstes Element</item_0001>
      <item_0002>Zweites Element</item_0002>
      <item_0003>Drittes Element</item_0003>
      <item_0004>Viertes Element</item_0004>
      <other_0001>Erstes Element</other_0001>
      <other_0002>Zweites Element</other_0002>
    </document>
    Challenge
    
    Select all elements with the name beginning with »item«.
    Desired selection (XML-output)
    
        <item_0001>Erstes Element</item_0001>
    
        <item_0002>Zweites Element</item_0002>
    
        <item_0003>Drittes Element</item_0003>
    
        <item_0004>Viertes Element</item_0004>
    
    Exercise
    Your input
 //*[contains(local-name(), "item")]

Selecting elements by name with namespaces

  Task
  Source document
  <document xmlns="http://example.org">
    <item_0001>Erstes Element</item_0001>
    <item_0002>Zweites Element</item_0002>
    <item_0003>Drittes Element</item_0003>
    <item_0004 xmlns="http://example.net/">Viertes Element</item_0004>
    <other_0001>Erstes Element</other_0001>
    <other_0002>Zweites Element</other_0002>
  </document>
  Challenge
  
  Select all elements having a name beginning with “item” and a namespace attached to “http://example.org”. For the expression, the prefix t is attached to the namespace “http://example.org”.
  Desired selection (XML-output)
  
      <item_0001 xmlns="http://example.org">Erstes Element</item_0001>
  
      <item_0002 xmlns="http://example.org">Zweites Element</item_0002>
  
      <item_0003 xmlns="http://example.org">Drittes Element</item_0003>
  
  Available prefix for the XPath-expression
  prefix    Namespace
  t http://example.org
  Exercise
  Your input
 //t:*[contains(local-name(), "item")]
 

Counting elements selected by certain criteria

  Task
  Source document
  <collection>
    <artist>
      <name>Robbie Williams</name>
      <cds>
        <cd>Rudebox</cd>
        <cd>Swing when you're winning</cd>
      </cds>
    </artist>
    <band>
      <name>Juli</name>
      <cds>
        <cd>Ein neuer Tag</cd>
      </cds>
    </band>
    <band>
      <name>Silbermond</name>
      <cds>
        <cd>Verschwende deine Zeit</cd>
      </cds>
    </band>
    <artist>
      <name>Michael Jackson</name>
      <cds>
        <cd>Bad</cd>
        <cd>Thriller</cd>
      </cds>
    </artist>
  </collection>
  Challenge
  
  Output in the sentence below how many albums in the collection are by solo artists (artist) and how many are by bands (band).
  Desired selection (text output)
  In der Sammlung gibt es 4 Alben von Solokünstlern und 2 Alben von Bands.
  Exercise
  Your input
  
concat("In der Sammlung gibt es ",  count(//artist/cds/cd)  ," Alben von Solokünstlern und ", count(//band/cds/cd), " Alben von Bands.")      

Content of a parent element

    Task
    Source document
    
    Your are at the green marked position
    <collection>
      <artist>
        <name>Robbie Williams</name>
        <cds>
          <cd>Rudebox</cd>
          <cd>Swing when you're winning</cd>
        </cds>
      </artist>
      <band>
        <name>Juli</name>
        <cds>
          <cd>Ein neuer Tag</cd>
        </cds>
      </band>
      <band>
        <name>Silbermond</name>
        <cds>
          <cd>Verschwende deine Zeit</cd>
        </cds>
      </band>
      <artist>
        <name>Michael Jackson</name>
        <cds>
          <cd>Bad</cd>
          <cd>Thriller</cd>
        </cds>
      </artist>
    </collection>
    Challenge
    
    Select the name of the artist that goes with the CD.
    Desired selection (text output)
    Robbie Williams
    Exercise
    Your input
//cd/ancestor::artist/name[text()]

Finding surrounding element

  Task
  Source document
  
  Your are at the green marked position
  <document id="1">
    <content>
      <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
        </head>
        <body>
          <div id="outer">
            <div id="inner">
              <ul>
                <li><a href="http://www.google.de/">Google</a>
                  <ul>
                    <li><a href="http://earth.google.de/">Google Earth</a></li>
                    <li><a href="http://picasa.google.de/intl/de/">Picasa</a></li>
                  </ul>
                </li> 
                <li><a href="http://www.heise.de/">Heise</a></li> 
                <li><a href="http://www.yahoo.de/">Yahoo</a></li> 
              </ul>
            </div>
          </div>
        </body>
      </html>
    </content>
  </document>
  Challenge
  
  Resolve the id-attribute of the div-element nearest to you. The expression selected by you should work at any point within the nested list.
  Desired selection (text output)
  inner
  Available prefix for the XPath-expression
  prefix    Namespace
  x http://www.w3.org/1999/xhtml
  Exercise
  Your input
//x:li/ancestor::x:ul/parent::x:div/@id

First and last element

Task
Source document
<collection>
  <artist>
    <name>Robbie Williams</name>
    <cds>
      <cd>Rudebox</cd>
      <cd>Swing when you're winning</cd>
    </cds>
  </artist>
  <band>
    <name>Juli</name>
    <cds>
      <cd>Ein neuer Tag</cd>
    </cds>
  </band>
  <band>
    <name>Silbermond</name>
    <cds>
      <cd>Verschwende deine Zeit</cd>
    </cds>
  </band>
  <artist>
    <name>Michael Jackson</name>
    <cds>
      <cd>Bad</cd>
      <cd>Thriller</cd>
    </cds>
  </artist>
</collection>
Challenge
Output the name of the first-listed CD by the last artist in the list.
Desired selection (text output)
Bad
Exercise
Your input
//artist[last()]//cd[position() = 1]

Changing character string

Task
Source document
<hooey>HTTP is a markup language.</hooey>
Challenge
Correct the false statement by means of XPath as specified below.
Desired selection (text output)
HTML is a markup language.
Exercise
Your input
translate(//hooey, "HTTP", "HTML")
Your result
HTTL is a markup language. 

Tady mají asi chybu v tom rozhraní, zlobí T a M za sebou. Když místo HTML napíšu jiný čtyřznakový řetězec, tak se bez problémů nahradí.

Counting nodes with condition

  Task
  Source document
  <jobs>
    <job priority="critical" name="Müll rausbringen" />
    <job priority="low" name="Möbel säubern" />
    <job priority="low" name="Teppich reinigen" />
    <job priority="medium" name="Fenster putzen" />
    <job priority="high" name="Pflanzen gießen" />
  </jobs>
  Challenge
  
  Output the number of jobs with the priority “low”.
  Desired selection (text output)
  2
  Exercise
  Your input
  count(//@priority[.="low"])

Comparisons in conditions

  Task
  Source document
  <jobs>
    <job name="cut Screens" availableBudget="8">
      <work usedBudget="3">Conception</work>
      <work usedBudget="3">Implementation</work>
      <work usedBudget="2.5">Implementation</work>
    </job>
    <job name="build HTML-demonstration" availableBudget="6">
      <work usedBudget="1.5">Conception</work>
      <work usedBudget="2.5">Implementation</work>
      <work usedBudget="2">Implementation</work>
    </job>
    <job name="CMS implementation" availableBudget="12">
      <work usedBudget="1">Data model</work>
      <work usedBudget="4">Editor-Customizing</work>
      <work usedBudget="4">Transformations</work>
      <work usedBudget="2">QS</work>
    </job>
  </jobs>
  Challenge
  
  Select all job elements with an exceeded budget (attribute “availableBudget”). Count the total number of used units (attribute “usedBudget”) of all work-elements of a job for this purpose.
  Desired selection (XML-output)
  
      <job name="cut Screens" availableBudget="8">
          <work usedBudget="3">Conception</work>
          <work usedBudget="3">Implementation</work>
          <work usedBudget="2.5">Implementation</work>
      </job>
  
  Exercise
  Your input
//job[@availableBudget < sum(./work/@usedBudget) ]

Calculating position

  Task
  Source document
  
  Your are at the green marked position
  <artist name="Robbie Williams">
    <cd name="Rudebox"> 
      <title>Rudebox</title>
      <title>Viva Life On Mars</title>
      <title>Lovelight (Lewis Taylor Cover)</title>
      <title>King Of The Bongo (Manu Chao Cover)</title>
      <title>Swing when you're winning</title>
      <title>Good Doctor</title>
    </cd> 
  </artist>
  Challenge
  
  Calculate the title number using its position.
  Desired selection (text output)
  5
  Exercise
  Your input
count(//cd//title[contains(., "Swing")]/preceding-sibling::title)+1

Changing small to capital letters

  Task
  Source document
  <text>this is a test</text>
  Challenge
  
  Change all small letters into capital letters.
  
  Note that the method »upper-case()« is a function of XPath 2.0. onion.net currently only supports functions from XPath 1.0.
  Desired selection (text output)
  THIS IS A TEST
  Exercise
  Your input    
  
  translate(//text, "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
  

Tohle je rada ze Stack Overflow.

Selecting querystring

  Task
  Source document
  <link>http://www.google.de/search?hl=de&amp;q=getit&amp;meta=</link>
  Challenge
  
  Select the text behind the question mark
  Desired selection (text output)
  hl=de&q=getit&meta=
  Exercise
  Your input
  substring-after( link , "?")
  Congratulations!
  
  You solved this exercise.
  Your result
  hl=de&q=getit&meta=

Elements with mixed text

  Task
  Source document
  <items>
    <item width="25px" />
    <item width="50px" />
    <item width="65px" />
    <item width="100px" />
    <item width="15pt" />
    <item width="40%" />
    <item width="25px" />
  </items>
  Challenge
  
  Output all item-elements that are specified in “px” and do not exceed the value of 70.
  
  Note that the method »ends-with()« is a function of XPath 2.0. onion.net currently only supports functions from XPath 1.0.
  Desired selection (XML-output)
  
      <item width="25px" />
  
      <item width="50px" />
  
      <item width="65px" />
  
      <item width="25px" />
  
  
  
  //item[number(substring-before (@width, "px")) < 70]

… několik cvičení vynecháno

Change XML document into CSV output

Task
Source document

Your are at the green marked position
<row>
  <cell name="id">1</cell>
  <cell name="firstName">Hans</cell>
  <cell name="lastName">Peter</cell>
  <cell name="age">44</cell>
</row>
Challenge

Change the XML representation into a comma-separated variant.
Desired selection (text output)
1;"Hans";"Peter";44
Exercise
Your input
concat(number(//cell[@name = "id"]), ";",'"', //cell[@name = "firstName"],'"', ";",'"', //cell[@name = "lastName"],'"', ";", number(cell[@name = "age"]))
Congratulations!

You solved this exercise.
Your result
1;"Hans";"Peter";44