joewiz
5/22/2014 - 5:02 PM

Principals & Chiefs whose positions ended after a certain date; using XQuery

Principals & Chiefs whose positions ended after a certain date; using XQuery

xquery version "3.0";
 
(: Displays a list of Principals & Chiefs whose positions ended after a certain date. :)
 
declare namespace output="http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "html5";
declare option output:media-type "text/html";
 
let $all-people := collection('/db/cms/apps/principals-chiefs/data/')/person
let $cut-off := '2008-06-01'
let $departures := $all-people//event[@type = ('missionterminated', 'appointmentterminated')][@when ge $cut-off]/ancestor::person
return
    <div>
        <h1>Principal Officers and Chiefs of Mission whose Appointment or Mission was Terminated After {format-date(xs:date($cut-off), '[MNn] [D], [Y]')}</h1>
        <h2>{format-date(current-date(), '[MNn] [D], [Y]')}</h2>
        <p>The appointments or missions of {count($departures)} principal officers and chiefs of mission were terminated on or after {format-date(xs:date($cut-off), '[MNn] [D], [Y]')}.</p>
        <ol>{
            for $person in $departures
            let $id := $person/@id
            let $name := string-join(($person/persName/surname, $person/persName/forename, $person/persName/genName[. ne '']), ', ')
            let $birth := if ($person/birth ne '') then $person/birth/string() else '?'
            let $roles :=
                string-join(
                    for $role in $person/role[event[@type = ('missionterminated', 'appointmentterminated') and @when ge $cut-off]]
                    let $role-label := collection('/db/cms/apps/principals-chiefs/code-tables/roles/data/')/role[id = $role/@type]/names/singular
                    let $location := if ($role/@location) then collection('/db/cms/apps/countries/data')/country[iso2 = $role/@location]/label/string() else ()
                    let $start := $role/event[@type = 'appointed']/@when
                    let $end := $role/event[@type = ('appointmentterminated', 'missionterminated')][1]/@when
                    order by $start
                    return
                        concat(
                            $role-label, 
                            ', ', 
                            if ($location) then 
                                concat($location, ', ')
                            else 
                                ()
                            ,
                            (: handle dates like yyyy-mm-dd :)
                            if (matches($start, '\d{4}-\d{2}-\d{2}')) then 
                                format-date(xs:date($start), '[MNn] [D], [Y]') 
                            (: handle dates like yyyy-mm :)
                            else if (matches($start, '\d{4}-\d{2}')) then
                                format-date(xs:date(concat($start, '-01')), '[MNn], [Y]') 
                            (: show asterisks for all other dates - unexpected input :)
                            else 
                                concat('***', $start, '***'),
                            (: sometimes empty date entries are intentional :)
                            if ($start = '' or empty($start)) then
                                if ($role/note or $end/parent::event/text() ne '') then
                                    ' (see note)'
                                else
                                    ()
                            else 
                                (),
                            '–', 
                            (: handle end dates as above :)
                            if ($end = '' or empty($end)) then 
                                '' 
                            else if (matches($end, '\d{4}-\d{2}-\d{2}')) then 
                                format-date(xs:date($end), '[MNn] [D], [Y]') 
                            else if (matches($end, '\d{4}-\d{2}')) then
                                format-date(xs:date(concat($end, '-01')), '[MNn], [Y]') 
                            else 
                                concat('***', $end, '***'),
                            if ($end = '' or empty($end)) then
                                if ($role/note or $end/parent::event/text() ne '') then
                                    ' (see note)'
                                else
                                    ()
                            else 
                                ()
                            )
                    , 
                    '; ')
            let $career-type := $person/career/string()
            order by $id
            return
                <li><a href="http://history.state.gov/departmenthistory/people/{$id}">{$name}</a> ({$career-type}, b. {$birth}): {$roles}.</li>
        }</ol>
    </div>