|
| 1 | +xquery version "1.0"; |
| 2 | +(: |
| 3 | +: Module Name: MARCXML AUTH to bibframe |
| 4 | +: |
| 5 | +: Module Version: 1.0 |
| 6 | +: |
| 7 | +: Date: 2012 Sept 13 |
| 8 | +: |
| 9 | +: Copyright: Public Domain |
| 10 | +: |
| 11 | +: Proprietary XQuery Extensions Used: None |
| 12 | +: |
| 13 | +: Xquery Specification: January 2007 |
| 14 | +: |
| 15 | +: Module Overview: Transforms a MARC AUTH record (name/title or title) |
| 16 | +: into its bibframe parts. |
| 17 | +: |
| 18 | +:) |
| 19 | + |
| 20 | +(:~ |
| 21 | +: Transforms a MARC AUTH record |
| 22 | +: into its bibframe parts. This is a *raw* |
| 23 | +: transform, meaning that it takes what it |
| 24 | +: can see and does what it can. To really make this |
| 25 | +: useable, additional work and modules will be necessary |
| 26 | +: |
| 27 | +: For examples of individual marc tags and subfield codes, look here: |
| 28 | +: http://lcweb2.loc.gov/natlib/util/natlib/marctags-nojs.html#[tag number] |
| 29 | +: |
| 30 | +: @author Kevin Ford (kefo@loc.gov) |
| 31 | +: @author Nate Trail (ntra@loc.gov) |
| 32 | +: @since January 30, 2014 |
| 33 | +: @version 1.0 |
| 34 | +:) |
| 35 | + |
| 36 | +module namespace marcauth2bibframe = 'info:lc/id-modules/marcauth2bibframe#'; |
| 37 | + |
| 38 | +(: MODULES :) |
| 39 | +import module namespace mbshared = 'info:lc/id-modules/mbib2bibframeshared#' at "module.MBIB-2-BIBFRAME-Shared.xqy"; |
| 40 | +import module namespace marcxml2madsrdf = "info:lc/id-modules/marcxml2madsrdf#" at "module.MARCXML-2-MADSRDF.xqy"; |
| 41 | +import module namespace music = "info:lc/id-modules/marcnotatedmusic2bf#" at "module.MBIB-NotatedMusic-2-BF.xqy"; |
| 42 | + |
| 43 | +import module namespace bfdefault = "info:lc/id-modules/marcdefault2bf#" at "module.MBIB-Default-2-BF.xqy"; |
| 44 | +import module namespace marcerrors = 'info:lc/id-modules/marcerrors#' at "module.ErrorCodes.xqy"; |
| 45 | +import module namespace modsxml2bibframe = 'info:lc/id-modules/modsxml2bibframe#' at "module.MODSXML-2-BIBFRAME.xqy"; |
| 46 | +import module namespace marc2bfutils = "info:lc/id-modules/marc2bfutils#" at "module.MARCXMLBIB-BFUtils.xqy"; |
| 47 | +(: NAMESPACES :) |
| 48 | +declare namespace marcxml = "http://www.loc.gov/MARC21/slim"; |
| 49 | +declare namespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; |
| 50 | +declare namespace rdfs = "http://www.w3.org/2000/01/rdf-schema#"; |
| 51 | + |
| 52 | +declare namespace bf = "http://bibframe.org/vocab/"; |
| 53 | +declare namespace bf2 = "http://bibframe.org/vocab2/";(: additional terms :) |
| 54 | +declare namespace madsrdf = "http://www.loc.gov/mads/rdf/v1#"; |
| 55 | +declare namespace relators = "http://id.loc.gov/vocabulary/relators/"; |
| 56 | +declare namespace hld = "http://www.loc.gov/opacxml/holdings/" ; |
| 57 | + |
| 58 | +(: VARIABLES :) |
| 59 | +declare function marcauth2bibframe:generate-work( |
| 60 | + $marcxml as element(marcxml:record), |
| 61 | + $workID as xs:string |
| 62 | + ) as element () |
| 63 | +{ |
| 64 | + |
| 65 | + let $cf008 := fn:string($marcxml/marcxml:controlfield[@tag='008']) |
| 66 | + let $leader:=fn:string($marcxml/marcxml:leader) |
| 67 | + let $leader6:=fn:substring($leader,7,1) |
| 68 | + let $leader7:=fn:substring($leader,8,1) |
| 69 | + let $leader19:=fn:substring($leader,20,1) |
| 70 | + |
| 71 | + let $typeOf008:= |
| 72 | + if ($leader6="a") then |
| 73 | + if (fn:matches($leader7,"(a|c|d|m)")) then |
| 74 | + "BK" |
| 75 | + else if (fn:matches($leader7,"(b|i|s)")) then |
| 76 | + "SE" |
| 77 | + else "" |
| 78 | + |
| 79 | + else |
| 80 | + if ($leader6="t") then "BK" |
| 81 | + else if ($leader6="p") then "MM" |
| 82 | + else if ($leader6="m") then "CF" |
| 83 | + else if (fn:matches($leader6,"(e|f|s)")) then "MP" |
| 84 | + else if (fn:matches($leader6,"(g|k|o|r)")) then "VM" |
| 85 | + else if (fn:matches($leader6,"(c|d|i|j)")) then "MU" |
| 86 | + else "" |
| 87 | + let $types := mbshared:get-resourceTypes($marcxml) |
| 88 | + |
| 89 | + let $mainType := "Work" |
| 90 | + |
| 91 | + let $uniformTitle := (:work title can be from 245 if no 240/130:) |
| 92 | + for $d in ($marcxml/marcxml:datafield[@tag eq "130"]|$marcxml/marcxml:datafield[@tag eq "240"])[1] |
| 93 | + return mbshared:get-uniformTitle($d) |
| 94 | + let $names := |
| 95 | + (for $d in $marcxml/marcxml:datafield[fn:matches(@tag,"(100|110|111)")] |
| 96 | + return mbshared:get-name($d), |
| 97 | + (:joined addl-names to names so we can get at least the first 700 if htere are no 1xx's into aap:) |
| 98 | + (:let $addl-names:= :) |
| 99 | + for $d in $marcxml/marcxml:datafield[fn:matches(@tag,"(700|710|711|720)")][fn:not(marcxml:subfield[@code="t"])] |
| 100 | + return mbshared:get-name($d) |
| 101 | + ) |
| 102 | + |
| 103 | + let $titles := |
| 104 | + <titles>{ |
| 105 | + for $t in $marcxml/marcxml:datafield[fn:matches(@tag,"(243|245|247)")] |
| 106 | + return mbshared:get-title($t, "work") |
| 107 | + }</titles> |
| 108 | + let $hashable := mbshared:generate-hashable($marcxml, $mainType, $types) |
| 109 | + (: Let's create an authoritativeLabel for this :) |
| 110 | + let $aLabel := |
| 111 | + if ($uniformTitle[bf:workTitle]) then |
| 112 | + fn:concat( fn:string($names[1]/bf:*[1]/bf:label), " ", fn:string($uniformTitle/bf:workTitle) ) |
| 113 | + else if ($titles) then |
| 114 | + fn:concat( fn:string($names[1]/bf:*[1]/bf:label), " ", fn:string($titles/bf:workTitle[1]) ) |
| 115 | + else |
| 116 | + "" |
| 117 | + |
| 118 | + let $aLabel := |
| 119 | + if (fn:ends-with($aLabel, ".")) then |
| 120 | + fn:substring($aLabel, 1, fn:string-length($aLabel) - 1 ) |
| 121 | + else |
| 122 | + $aLabel |
| 123 | + |
| 124 | + let $aLabel := |
| 125 | + if ($aLabel ne "") then |
| 126 | + element bf:authorizedAccessPoint { fn:normalize-space($aLabel) } |
| 127 | + else |
| 128 | + () |
| 129 | + |
| 130 | + let $langs := mbshared:get-languages ($marcxml) |
| 131 | + let $work-classes := mbshared:generate-classification($marcxml,"work") |
| 132 | + let $work-identifiers := mbshared:generate-identifiers($marcxml,"work") |
| 133 | + let $admin:=mbshared:generate-admin-metadata($marcxml, $workID) |
| 134 | + let $subjects:= |
| 135 | + for $d in $marcxml/marcxml:datafield[fn:matches(fn:string-join($marc2bfutils:subject-types//@tag," "),fn:string(@tag))] |
| 136 | + return mbshared:get-subject($d) |
| 137 | + let $derivedFrom:= |
| 138 | + element bf:derivedFrom { |
| 139 | + attribute rdf:resource{fn:concat($workID,".marcxml.xml")} |
| 140 | + } |
| 141 | +return $marcxml |
| 142 | +(: |
| 143 | + element {fn:concat("bf:" , $mainType)} { |
| 144 | + attribute rdf:about {$workID}, |
| 145 | + |
| 146 | + for $t in fn:distinct-values($types) |
| 147 | + return |
| 148 | + element rdf:type { |
| 149 | + attribute rdf:resource {fn:concat("http://bibframe.org/vocab/", $t)} |
| 150 | + }, |
| 151 | + $aLabel, |
| 152 | + |
| 153 | + if ($uniformTitle/bf:workTitle) then |
| 154 | + $uniformTitle/* |
| 155 | + else |
| 156 | + $titles/* , |
| 157 | + |
| 158 | + $names, |
| 159 | + $langs, |
| 160 | + $subjects, |
| 161 | + $work-classes, |
| 162 | + $work-identifiers, |
| 163 | + $derivedFrom, |
| 164 | + $hashable, |
| 165 | + $admin |
| 166 | + }:) |
| 167 | + |
| 168 | +}; |
| 169 | + |
| 170 | +(:~ |
| 171 | +: This is the main function. It expects a MARCXML record as input. |
| 172 | +: |
| 173 | +: It generates bibframe RDF data as output. |
| 174 | +: |
| 175 | +: |
| 176 | +: @param $collection element is the top level (marcxml ?) |
| 177 | +: @return rdf:RDF as element() |
| 178 | +:) |
| 179 | +declare function marcauth2bibframe:marcauth2bibframe( |
| 180 | + $collection as element(), |
| 181 | + $identifier as xs:string |
| 182 | + ) |
| 183 | +{ marcauth2bibframe:marcauth2bibframe($collection/marcxml:record[1], "123") |
| 184 | +(: for $marcxml in $collection/marcxml:record |
| 185 | + let $error := marcerrors:check($marcxml) |
| 186 | + let $out := |
| 187 | + if ($error) then |
| 188 | + $error |
| 189 | + else |
| 190 | + let $about := |
| 191 | + if ($identifier eq "") then |
| 192 | + () |
| 193 | + else if ( fn:not( fn:starts-with($identifier, "http://") ) ) then |
| 194 | + attribute rdf:about { fn:concat("http://id.loc.gov/" , $identifier) } |
| 195 | + else |
| 196 | + attribute rdf:about { $identifier } |
| 197 | + |
| 198 | + |
| 199 | + |
| 200 | + |
| 201 | + let $workID:=fn:normalize-space(fn:string($marcxml/marcxml:controlfield[@tag="001"])) |
| 202 | + let $work:=marcauth2bibframe:marcauth2bibframe($marcxml, $workID) |
| 203 | + return |
| 204 | + <rdf:RDF |
| 205 | + xmlns:rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
| 206 | + xmlns:rdfs = "http://www.w3.org/2000/01/rdf-schema#" |
| 207 | + xmlns:bf = "http://bibframe.org/vocab/" |
| 208 | + xmlns:madsrdf = "http://www.loc.gov/mads/rdf/v1#" |
| 209 | + xmlns:relators = "http://id.loc.gov/vocabulary/relators/" |
| 210 | + > |
| 211 | + { |
| 212 | + |
| 213 | + element bf:test { $work } |
| 214 | + } |
| 215 | + </rdf:RDF> |
| 216 | + return $out:) |
| 217 | + |
| 218 | +}; |
| 219 | +(: |
| 220 | +: main function |
| 221 | +:) |
| 222 | +declare function marcauth2bibframe:marcauth2bibframe( |
| 223 | + $collection as element() |
| 224 | + ) as element(rdf:RDF) |
| 225 | +{ |
| 226 | + let $identifier := fn:string(fn:current-time()) |
| 227 | + let $identifier := fn:replace($identifier, "([:\-]+)", "") |
| 228 | + return |
| 229 | + if ($collection/*[fn:local-name()='mods'] ) then |
| 230 | + modsxml2bibframe:modsxml2bibframe($collection) |
| 231 | + else |
| 232 | + marcauth2bibframe:marcauth2bibframe($collection,$identifier) |
| 233 | +}; |
| 234 | + |
| 235 | +declare function marcauth2bibframe:modsbib2bibframe( |
| 236 | + $collection as element() |
| 237 | + ) as element(rdf:RDF) |
| 238 | +{ |
| 239 | + modsxml2bibframe:modsxml2bibframe($collection) |
| 240 | + |
| 241 | +}; |
| 242 | + |
| 243 | + |
| 244 | + |
0 commit comments