Skip to content

Instantly share code, notes, and snippets.

@timathom
Last active August 29, 2015 14:02
Show Gist options
  • Save timathom/f36ee60e51dec54545bc to your computer and use it in GitHub Desktop.
Save timathom/f36ee60e51dec54545bc to your computer and use it in GitHub Desktop.
XQuery Institute Sandbox
(: Looking for Antony's longest speech in "Julius Caesar." Is there a better path? :)
//ab[parent::sp/speaker[w="ANTONY"]][count(.//w) eq max(//ab[parent::sp/speaker[w="ANTONY"]]/count(.//w))]
================================
declare default element namespace "http://www.tei-c.org/ns/1.0";
<speech>{
for $sp in //sp
let $speaker := $sp/speaker
for $ab in $sp/ab
return (
<speaker>{ $sp/@who, $speaker/w/text() }</speaker>,
<ab>{ normalize-space(string($ab)) }</ab>
)
}</speech>
================================
declare default element namespace "http://www.tei-c.org/ns/1.0";
declare namespace test="http://speeches.org";
<test:speeches>{
for $sp in //sp
let $text := $sp//ab//(w | c | pc)/text()
let $speaker := $sp/speaker/w/text()
let $lineCount := count($sp//ab//milestone)
let $stage := $sp//stage
order by $speaker[1] ascending, $lineCount descending
return (
<test:speech>{
<test:speaker>{ $sp/@who, $speaker }</test:speaker>,
if (exists($stage))
then
<test:stage>{
for $s in $stage
return normalize-space(string($s))
}</test:stage>
else ( ),
<test:text>{ $text }</test:text>,
<test:lines>{ $lineCount }</test:lines>
}</test:speech>
)
}</test:speeches>
================================
declare default element namespace "http://www.tei-c.org/ns/1.0";
for $person in //person
let $stage := //stage
where $person/@xml:id = $stage/@who ! tokenize(., " |#")
order by $person/@xml:id
return
<person_stage>{
<person>{ $person/@xml:id }</person>,
for $s in $stage[@who ! tokenize(., " |#") = $person/@xml:id]
return
<stage>{
$s//(w | c | pc)/text()
}</stage>
}</person_stage>
================================
BETTER:
declare default element namespace "http://www.tei-c.org/ns/1.0";
for $person in //person
let $stage := //stage
order by $person/@xml:id
return
<person_stage>{
<person>{ $person/@xml:id }</person>,
for $s in $stage
where $person/@xml:id = $s/@who ! tokenize(., " |#")
return
<stage>{
$s//(w | c | pc)/text()
}</stage>
}</person_stage>
================================
SAME THING IN XSLT 2.0:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs"
xpath-default-namespace="http://www.tei-c.org/ns/1.0" version="2.0">
<xsl:template match="/">
<root>
<xsl:apply-templates select="//person, //stage">
<xsl:sort select="@xml:id" order="ascending"/>
</xsl:apply-templates>
</root>
</xsl:template>
<xsl:template match="person">
<xsl:variable name="pID" select="@xml:id"/>
<person_stage>
<person xml:id="{@xml:id}"/>
<xsl:for-each select="//stage[tokenize(@who, ' |#') = $pID]">
<stage>
<xsl:value-of select="(w | c | pc)/text()"/>
</stage>
</xsl:for-each>
</person_stage>
</xsl:template>
<xsl:template match="@*|node()"/>
</xsl:stylesheet>
================================
Group all actors by Act and Scene:
declare default element namespace "http://www.tei-c.org/ns/1.0";
for $act in //div1
for $scene in $act//div2
for $actor in $scene//stage/@who ! tokenize(.,'#| #')
group by $actor
order by $actor
return
<actor_by_act>{
<actor>{ $actor }</actor>,
for $a in $act/@n
for $s in $scene/@n
let $key := concat($a, '.', $s)
group by $key
order by $key
return
<act n="{ $key }"/>
}</actor_by_act>
==========================
IN PROGRESS
declare default element namespace "http://www.tei-c.org/ns/1.0";
for $act in //div1
for $scene in $act/div2
for $actor in $scene/stage/@who ! tokenize(.,'#| ')
group by $actor
order by $actor
return
<actor_by_act>{
<actor>{ exists($actor) }</actor>,
for $a in $act/@n
group by $a
order by $a
return
<scene n="{ $a }"/>
}</actor_by_act>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment