Skip to content

Instantly share code, notes, and snippets.

@mjlassila
Created May 5, 2014 08:20
Show Gist options
  • Save mjlassila/86da5719ac420e7fdf2f to your computer and use it in GitHub Desktop.
Save mjlassila/86da5719ac420e7fdf2f to your computer and use it in GitHub Desktop.
XQuery module for creating MARC21 records
module namespace marc = 'app.marc.generator';
declare function marc:zero-prefix-time($timestamp as xs:string) {
let $time:=xs:string($timestamp)
let $prefixed_time:=
if(string-length($time) < 2) then
concat(0,$time)
else $time
return $prefixed_time
};
declare function marc:create-marc-timestamp($context as xs:string) as xs:string {
let $timestamp:=fn:current-dateTime()
let $year:=xs:string(fn:year-from-dateTime($timestamp))
let $month:=marc:zero-prefix-time(xs:string(fn:month-from-dateTime($timestamp)))
let $day:=marc:zero-prefix-time(xs:string(fn:day-from-dateTime($timestamp)))
let $hours:=marc:zero-prefix-time(xs:string(fn:hours-from-dateTime($timestamp)))
let $minutes:=marc:zero-prefix-time(xs:string(fn:minutes-from-dateTime($timestamp)))
let $seconds:=substring-before(marc:zero-prefix-time(xs:string(fn:seconds-from-dateTime($timestamp))),'.')
let $marc-timestamp:=
if($context eq '005') then
concat($year,$month,$day,$hours,$minutes,$seconds,'.0')
else if ($context eq '008') then
concat(substring($year,3,2),$month,$day)
else()
return $marc-timestamp
};
declare function marc:leader($series as element(isbnFormSeries)?) as element(){
let $bibliographic_level:=
if (string-length($series)>2) then
's'
else ('m'
)
return
<leader>{concat('00000na',$bibliographic_level,' a22000008i 4500')}</leader>
};
declare function marc:field-001($node as element(btitle)) as element() {
<controlfield tag="001">69876</controlfield>
};
declare function marc:field-005() as element() {
<controlfield tag="005">{marc:create-marc-timestamp('005')}</controlfield>
};
declare function marc:field-008($year as element(isbnFormPublishingYear)?, $language as element()?) as element() {
let $timestamp:=marc:create-marc-timestamp('008')
let $publishing_date_type:='s'
let $publishing_date:=if ($year) then
$year
else ('||||')
let $publishing_date_spacer:=' '
let $place_of_publication:='fi'
let $filler:=' ||||||| |||||||'
let $language:=
if (contains($language,'fi')) then
'fin'
else if (contains($language,'sv')) then
'swe'
else if (contains($language,'en')) then
'eng'
else (
'fin'
)
let $trailing_filler:='||'
return <controlfield tag="008">{
concat(
$timestamp,
$publishing_date_type,
$publishing_date,
$publishing_date_spacer,
$place_of_publication,
$filler,
$language,
$trailing_filler
)}</controlfield>
};
declare function marc:field-020($isbn as element(isbnFormISBN), $format as element(isbnFormFormat)) as element() {
<datafield tag="020" ind1=" " ind2=" ">
<subfield code="a">{data($isbn)}</subfield>
<subfield code="q">{data($format)}</subfield>
</datafield>
};
declare function marc:field-041($language as element(isbnFormLang)?) as element() {
let $subfield_a:=
if (string-length($language) eq 3) then
<subfield code="a">{data($language)}</subfield>
else (
<subfield code="a">fin</subfield>
)
return
<datafield tag="041" ind1="0" ind2=" ">
{$subfield_a}
</datafield>
};
declare function marc:field-100($author as node()*) as element()? {
let $subfield_e:=
if (string-length($author/@role)>2) then
<subfield code="e">{concat($author/@role,'.')}</subfield>
else()
return
(:Onko kyseessä teos, jolla on päävastuullinen tekijä?:)
if(string-length($author/@surname)>=2) then
<datafield tag="100" ind1="1" ind2=" ">
<subfield code="a">{concat($author/@surname,', ',$author/@firstname,',')}</subfield>
<subfield code="c">ennakkotieto.</subfield>
{$subfield_e}
</datafield>
else()
};
declare function marc:field-245($title as element(isbnFormTitle), $subtitle as element(isbnFormSubtitle)*) as element() {
let $subfield_b:=
if(string-length($subtitle)>2) then
<subfield code="b">{concat(data($subtitle),'.')}</subfield>
else ()
let $subfield_a:=
if(string-length($subtitle)>2) then
<subfield code="a">{concat(data($title),' :')}</subfield>
else (
<subfield code="a">{data($title)}</subfield>
)
return
<datafield tag="245" ind1="1" ind2="0">
{$subfield_a}
{$subfield_b}
</datafield>
};
declare function marc:field-260($publisher as element(isbnFormPublishingHouse), $year as element(isbnFormPublishingYear)) as element()? {
let $subfield_b:=
if(string-length($publisher)>2 and string-length($year)>2) then
<subfield code="b">{concat(data($publisher),',')}</subfield>
else if (string-length($publisher)>2) then
<subfield code="b">{data($publisher)}</subfield>
else ()
let $subfield_c:=
if(string-length($publisher)>2 and string-length($year)>2) then
<subfield code="c">{concat(data($year),'.')}</subfield>
else ()
return
if ($subfield_b and $subfield_c) then
<datafield tag="260" ind1=" " ind2=" ">
{$subfield_b}
{$subfield_c}
</datafield>
else()
};
declare function marc:field-263($year as element(isbnFormPublishingYear)) as element() {
<datafield tag="263" ind1=" " ind2=" ">
<subfield code="a">{concat(data($year),'--')}</subfield>
</datafield>
};
declare function marc:field-336() as element() {
<datafield tag="336" ind1=" " ind2=" ">
<subfield code="a">Teksti</subfield>
</datafield>
};
declare function marc:field-337() as element() {
<datafield tag="337" ind1=" " ind2=" ">
<subfield code="a">ei välittävää laitetta</subfield>
</datafield>
};
declare function marc:field-490(
$series as element(isbnFormSeries)*,
$volume as element(isbnFormVolume)*,
$issn as element(ISSN)?) as element()? {
if (string-length($series)>2 and string-length($volume)>=1 and string-length($issn)>=1) then
<datafield tag="490" ind1="0" ind2=" ">
<subfield code="a">{concat(data($series),',')}</subfield>
<subfield code="v">{data($volume)}</subfield>
<subfield code="x">{data($issn)}</subfield>
</datafield>
else if (string-length($series)>2) then
<datafield tag="490" ind1="0" ind2=" ">
<subfield code="a">{data($series)}</subfield>
</datafield>
else()
};
declare function marc:field-500() as element() {
<datafield tag="500" ind1=" " ind2=" ">
<subfield code="a">ENNAKKOTIET CIP/JYK</subfield>
</datafield>
};
declare function marc:field-700($authors as node()*) as node()* {
for $author in $authors/author
let $subfield_e:=
if (string-length($author/@role)>2) then
<subfield code="e">{concat($author/@role,'.')}</subfield>
else()
return
if ($author/@surname) then
<datafield tag="700" ind1="1" ind2=" ">
<subfield code="a">{concat($author/@surname,', ',$author/@firstname,',')}</subfield>
<subfield code="c">ennakkotieto.</subfield>
{$subfield_e}
</datafield>
else()
};
declare function marc:create-marcxml($record as node()) as node() {
let $authors:=
<authors>
{
for $i in (1,2,3,4,5)
let $firstname:= $record/*[fn:node-name(.) =
xs:QName(concat('isbnFormAuthor',$i,'Firstname'))]
let $surname:= $record/*[fn:node-name(.) =
xs:QName(concat('isbnFormAuthor',$i,'Surname'))]
let $role:= $record/*[fn:node-name(.) =
xs:QName(concat('isbnFormAuthor',$i,'Role'))]
let $author_exists:=string-length(concat($firstname,$surname))>6
return if ($author_exists) then
<author surname="{$surname}" firstname="{$firstname}" role="{$role}"/>
else()
}
</authors>
return
<record>
{marc:leader($record/isbnFormSeries)}
<controlfield tag="001">0000000</controlfield>
{marc:field-005()}
{marc:field-008($record/isbnFormPublishingYear,$record/isbnFormPublishingLang)}
{marc:field-020($record/isbnFormISBN, $record/isbnFormFormat)}
{marc:field-041($record/isbnFormLang)}
{marc:field-245($record/isbnFormTitle,$record/isbnFormSubtitle)}
{marc:field-100($authors/author[@role="author"][1])}
{marc:field-260($record/isbnFormPublishingHouse,$record/isbnFormPublishingYear)}
{marc:field-263($record/isbnFormPublishingYear)}
{marc:field-336()}
{marc:field-337()}
{marc:field-490($record/isbnFormSeries,$record/isbnFormVolume,$record/ISSN)}
{marc:field-500()}
{marc:field-700($authors)}
</record>
};
declare function marc:create-marc($marcxml as node()) as xs:string {
let $file:= file:write('/tmp/temporary-marcxml.xml',$marcxml, map { "method" := "xml"})
let $output:=
proc:execute('/usr/local/bin/yaz-marcdump', ('-i','marcxml', '-o','marc', '/tmp/temporary-marcxml.xml'))
return
if ($output/code eq '0') then
data($output//output)
else(
'Virhe MARC-muunnoksessa'
)
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment