index-api.xqm 6.05 KB
Newer Older
1
2
xquery version "3.1";
(:~
3
 : This module provides an API to retrieve index entries as a sequence for a
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 : given page.
 :
 : @author Mathias Göbel
 : @version 1.0
 : @since 2.5.6
 : :)

module namespace index="https://fontane-nb.dariah.eu/indexapi";

declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare namespace tei="http://www.tei-c.org/ns/1.0";
declare namespace test="http://exist-db.org/xquery/xqsuite";
declare namespace xhtml="http://www.w3.org/1999/xhtml";

import module namespace rest="http://exquery.org/ns/restxq";
import module namespace config="http://textgrid.de/ns/SADE/config" at "../config/config.xqm";

Mathias Goebel's avatar
Mathias Goebel committed
21
22
declare variable $index:dataPath := "/db/sade-projects/textgrid/data/xml/data";

23
24
25
26
27
(:~
 : resolves and lists all references on a given page based on their index data
 :
 : @param $uri – A valid TextGrid Base-URI without prefix
 : @param $surface – a string to match a tei:surface/@n in the document
Mathias Goebel's avatar
Mathias Goebel committed
28
 : (use “-” as delimiter)
29
30
31
32
33
34
35
36
37
38
39
 : @return a list with all entries
 : @see http://localhost:8080/exist/restxq/fontane/index/16b00/62v
 : @see https://fontane-nb.dariah.eu/api/index/16b00/62v
 :  :)
declare
  %rest:GET
  %rest:path("fontane/index/{$uri}/{$surface}")
  %output:method("html")

  %test:name("entities per page")

40
  %test:args("16b00", "2v") (: return empty sequence on interleaf :)
41
42
  %test:assertEmpty

43
44
  %test:args("", "") (: return custom error INDEX-API1 :)
  %test:assertError("INDEX-API1")
45

46
47
48
  %test:args("16b00", "foo") (: return custom error INDEX-API2 :)
  %test:assertError("INDEX-API2")

49
50
51
52
53
54
55
56
  %test:args("16b00", "1r") (: return more then 10 entities :)
  %test:assertXPath("count($result//xhtml:li) gt 10")

  %test:args("16b00", "2r") (: return 4 groups :)
  %test:assertXPath("count($result) eq 4")

function index:entites-per-page($uri as xs:string, $surface as xs:string)
as element(xhtml:ul)* {
Mathias Goebel's avatar
Mathias Goebel committed
57
let $docpath := $index:dataPath || "/" || $uri || ".xml"
Mathias Goebel's avatar
Mathias Goebel committed
58
let $surface := tokenize($surface, "-")
59
60
61
62

(: test for document available :)
return
  if(not(doc-available($docpath)))
63
  then
Mathias Goebel's avatar
Mathias Goebel committed
64
    let $docsInDb := collection($index:dataPath)//tei:sourceDoc
65
        /replace(base-uri(), "\.xml|/|db|sade-projects|textgrid|data|xml", "")
66
67
68
69
70
71
        => string-join(", ")
    return
      error(QName("FONTANE", "INDEX-API1"), "Unable to resolve URI. Try one of " || $docsInDb || "." )
  else

let $doc := doc($docpath)
72
73
let $page := $doc//tei:surface[@n = $surface]

74
(: test for surface available :)
Mathias Goebel's avatar
Mathias Goebel committed
75
return if(not(exists($page)))
76
  then
77
78
79
80
81
82
    let $surfacesInDocument := $doc//tei:surface[@n]/string(@n)
        => string-join(", ")
    return
      error(QName("FONTANE", "INDEX-API2"), "tei:surface not found. Try one of " || $surfacesInDocument || "." )
else

83
(: test for entries before further processing :)
84
if(not(exists($page//tei:rs))) then () else
85

86
let $entities := $page//tei:rs/tokenize(@ref, " ") => distinct-values()
87
88
89
90
91
92
let $groups := $entities ! substring-before(., ":") => distinct-values()

for $group in $groups
let $translate := local:translate-prefix($group, (count($entities[substring-before(., ":") = $group]) gt 1) )
order by $translate
return
93
94
95
96
97
98
99
  element xhtml:ul {
    element xhtml:li {
      attribute class {"group", $group},
      $translate,
      element xhtml:ul {
        for $entity in $entities[substring-before(., ":") = $group]
        let $ref := substring-after($entity, ":")
Mathias Goebel's avatar
Mathias Goebel committed
100
        let $index := (collection($index:dataPath)/id($ref))[1]
101
        let $name := string($index/*[1])
Mathias Goebel's avatar
Mathias Goebel committed
102
103
        let $list := local:get-list-by-id($ref)
        let $href := "register-" || $list || ".html?e=" || $ref
104
105
106
107
108
109
        order by $name
        return
          element xhtml:li {
            attribute data-ref { $entity },
            attribute class { $index/local-name() },
            element xhtml:a {
Mathias Goebel's avatar
Mathias Goebel committed
110
              attribute href { $href },
111
112
              attribute target { "_blank" },
              $name
113
            }
114
115
          }
      }
116
    }
117
  }
118
119
120
};

(:~
121
 : Translate an index prefix into German.
122
 : @param $prefix a three letter code to resolve
123
 : @param $plural true when plural translation is required
124
125
126
127
128
129
 : @response the translation
 :   :)
declare function local:translate-prefix($prefix as xs:string, $plural as xs:boolean)
as xs:string {
if ($plural)
then
130
131
132
133
134
135
  switch ($prefix)
    case "eve" return "Ereignisse"
    case "psn" return "Personen"
    case "plc" return "Orte"
    case "org" return "Institutionen"
    case "wrk" return "Werke"
Mathias Goebel's avatar
Mathias Goebel committed
136
    default return "The prefix " || $prefix || " is not in the dictonary."
137
else
138
139
140
141
142
143
  switch ($prefix)
    case "eve" return "Ereignis"
    case "psn" return "Person"
    case "plc" return "Ort"
    case "org" return "Institution"
    case "wrk" return "Werk"
Mathias Goebel's avatar
Mathias Goebel committed
144
    default return "The prefix " || $prefix || " is not in the dictonary."
145
};
Mathias Goebel's avatar
Mathias Goebel committed
146

Mathias Goebel's avatar
Mathias Goebel committed
147
148
149
150
151
152
153
154
155
156
declare
  %test:name("entity list relation")

  %test:args("Dom_Karlos_Figur") (: person in wrk :)
  %test:assertEquals("list-works")

  %test:args("Purschian") (: person :)
  %test:assertEquals("listPerson")

function local:get-list-by-id($id as xs:string)
Mathias Goebel's avatar
Mathias Goebel committed
157
as xs:string {
Mathias Goebel's avatar
Mathias Goebel committed
158
let $entity := collection($index:dataPath)/id($id)
159
let $test := if($entity[2]) then error(QName("FONTANE", "INDEX-API3"), "Entity »" || $id || "« has more then one occurence." ) else ()
Mathias Goebel's avatar
Mathias Goebel committed
160
161
162
163
164
165
166
return
    switch ( $entity/local-name() )
        case "event" return "listEvent"
        case "org" return "listOrg"
        case "place" return "listPlace"
        case "person" return
            if($entity/ancestor::tei:item)
Mathias Goebel's avatar
Mathias Goebel committed
167
            then local:get-list-by-id( ($entity/ancestor::tei:item)[last()]/string(@xml:id) )
Mathias Goebel's avatar
Mathias Goebel committed
168
169
170
            else "listPerson"
        case "personGrp" return
            if($entity/ancestor::tei:item)
Mathias Goebel's avatar
Mathias Goebel committed
171
            then local:get-list-by-id( ($entity/ancestor::tei:item)[last()]/string(@xml:id) )
Mathias Goebel's avatar
Mathias Goebel committed
172
173
174
175
176
177
            else "listPerson"
        default return
            let $list := ($entity/ancestor::tei:list[@type])[last()]
            return
                $list/local-name() || "-" || string($list/@type)
};
Mathias Goebel's avatar
Mathias Goebel committed
178
179
180
181
182
183
184
185
186

declare
  %rest:GET
  %rest:path("fontane/index/entity/{$id}")
  %output:method("html")
function index:rendered-entity($id as xs:string)
as element(xhtml:li)? {
    doc("/db/sade-projects/textgrid/data/xml/xhtml/index.xml")//xhtml:li[@id = $id]
};