XQuery/Alphabet Poster

From Wikibooks, open books for an open world
Jump to navigation Jump to search

This toy programme creates alphabet posters using images from Wikipedia, located via dbpedia.

It is described in a blog entry

Script[edit | edit source]

(:  
  This script  creates a picture alphabet based on a list of words.  
  The pictures are from wikipedia, found via dbpedia.
  
  This was created for  Charlie Taylor (age 5 ) for his animal alphabet.
  
  @parameter  title - The title string for the poster 
  @parameter  alphabet - list of comma-separated word , unordered
  @parameter cols - the number of columns in the table layout
  @parameter  action : poster - generate the poster, editor generate the editor for the data
  @author Chris Wallace
  @date 2008-10-22
  
:)
declare namespace r = "http://www.w3.org/2005/sparql-results#";

declare variable $alphabet := request:get-parameter("alphabet","Ant,Bat");
declare variable $words := tokenize(normalize-space($alphabet)," *, *");
declare variable $title := request:get-parameter("title","Charlie's Animal  Alphabet");
declare variable $cols := xs:integer(request:get-parameter("cols",4));
declare variable $action := request:get-parameter("action","edit");

declare variable  $query := "
PREFIX : <http://dbpedia.org/resource/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT * WHERE { 
      :Hedgehog  foaf:depiction ?img.
   }
";

declare function local:execute-sparql($query as xs:string)  {
  let $sparql := concat("http://dbpedia.org/sparql?format=xml&amp;default-graph-uri=http://dbpedia.org&amp;query=",
                               encode-for-uri($query)
                           )
  return  doc($sparql)
};


declare function local:picture($animal as xs:string )  as xs:string {
 let $queryx := replace($query,"Hedgehog",replace($animal," ","_"))
 let $result:= local:execute-sparql($queryx)
 return string($result//r:result[1]//r:uri)
};

declare function local:cell ($animal as xs:string , $picture as xs:string) as element(td) {
 let $letter := substring($animal,1,1)
 return 
     <td class="cell" valign="top">
            <span class="letter">{$letter} </span>
             is for 
              <div>
            <a href="http://en.wikipedia.org/wiki/{$animal}">
           <img src="{$picture}"  
                alt="{$animal}" 
                title="{$animal}" 
                border="0"
            />   
           </a>
           </div>
           <span class="word">
                {$animal}
            </span>
      </td>

};

declare function local:poster() as element(div) {
    <div>
      <h1>{$title}  </h1>
      {let $letters := 
         for $animal in $words
         let $picture := local:picture($animal)
         order by $animal
         return 
             local:cell($animal,$picture)
       let $nrows := xs:integer(ceiling(count($letters) div $cols))
       return
         <table>
           {for $row in (1 to $nrows)
            return
             <tr>
                {for $col in (1 to $cols)
                 let $letter := $letters[position()= ($row - 1 ) * $cols + $col]
                 return
                   if ($letter) 
                   then $letter
                   else <td> </td>
                }
             </tr>
            }
         </table>
       }
    </div>
  };
  
declare function local:editor() as element(form) {
<form action="alphabet.xq" method="get">
   <input type="hidden" name="action" value="poster"/>
   <div> <label for="title">Title of Alphabet</label><input type="text" name="title" value="{$title}"size="50"/></div>
   <div> <label for="cols">Number of Columns</label><input type="text" name="cols" value="{$cols}"size="2"/></div>
   <div> <label for="alphabet">Alphabet words, unordered, separated by  ,  </label>
   <br/>
   <textarea name="alphabet" cols="80" rows="5">
   {$alphabet}
   </textarea>
   </div>
   <input type="submit" value="Create Alphabet Poster"/>
</form>
};

declare option exist:serialize "method=xhtml media-type=text/html";

<html>
   <head>
       <title>Alphabet Poster - {$action}</title>
       <style>
        <![CDATA[
         body {font-family:Comic Sans MS;}
         div.cell {margin: 0 5px 10px 0; }
         span.letter  {font-size:200%;}
         span.word {display:none;}
         ]]>
       </style>
       <style media="print">
       <![CDATA[
         .nav {display:none}
         span.word {display:block; font-size:120%;font-family:Comic Sans MS; }
         ]]>
       </style>
   </head>
   <body>
  {
if ($action = "poster")
then (<span class="nav"><a href="alphabet.xq?alphabet={string-join($words,", ")}&amp;title={$title}&amp;cols={$cols}&amp;action=edit"> [edit]</a></span> ,
           local:poster()
          )
else  if ($action="edit")
then local:editor()
else ()
 }
  </body>
</html>