bibframe_ruby 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +24 -2
  3. data/docs/superpowers/plans/2026-09-09-marc-conversion.md +537 -0
  4. data/docs/superpowers/specs/2026-09-09-marc-conversion-design.md +110 -0
  5. data/lib/bibframe_ruby/marc_converter.rb +67 -0
  6. data/lib/bibframe_ruby/parser.rb +4 -2
  7. data/lib/bibframe_ruby/version.rb +1 -1
  8. data/lib/bibframe_ruby.rb +7 -0
  9. data/vendor/marc2bibframe2/xsl/ConvSpec-001-007.xsl +2276 -0
  10. data/vendor/marc2bibframe2/xsl/ConvSpec-006,008.xsl +1295 -0
  11. data/vendor/marc2bibframe2/xsl/ConvSpec-010-048.xsl +1712 -0
  12. data/vendor/marc2bibframe2/xsl/ConvSpec-050-088.xsl +713 -0
  13. data/vendor/marc2bibframe2/xsl/ConvSpec-1XX,7XX,8XX-names.xsl +1141 -0
  14. data/vendor/marc2bibframe2/xsl/ConvSpec-200-247not240-Titles.xsl +771 -0
  15. data/vendor/marc2bibframe2/xsl/ConvSpec-240andX30-UnifTitle.xsl +535 -0
  16. data/vendor/marc2bibframe2/xsl/ConvSpec-250-270.xsl +283 -0
  17. data/vendor/marc2bibframe2/xsl/ConvSpec-3XX.xsl +2245 -0
  18. data/vendor/marc2bibframe2/xsl/ConvSpec-460-468-SeriesTreat.xsl +135 -0
  19. data/vendor/marc2bibframe2/xsl/ConvSpec-490-510-Links.xsl +145 -0
  20. data/vendor/marc2bibframe2/xsl/ConvSpec-5XX.xsl +1448 -0
  21. data/vendor/marc2bibframe2/xsl/ConvSpec-600-662.xsl +1417 -0
  22. data/vendor/marc2bibframe2/xsl/ConvSpec-720+740to755.xsl +333 -0
  23. data/vendor/marc2bibframe2/xsl/ConvSpec-758.xsl +102 -0
  24. data/vendor/marc2bibframe2/xsl/ConvSpec-760-788-Links.xsl +771 -0
  25. data/vendor/marc2bibframe2/xsl/ConvSpec-841-887.xsl +328 -0
  26. data/vendor/marc2bibframe2/xsl/ConvSpec-880.xsl +119 -0
  27. data/vendor/marc2bibframe2/xsl/ConvSpec-ControlSubfields.xsl +495 -0
  28. data/vendor/marc2bibframe2/xsl/ConvSpec-LDR.xsl +183 -0
  29. data/vendor/marc2bibframe2/xsl/ConvSpec-Preprocess0-Splitting.xsl +765 -0
  30. data/vendor/marc2bibframe2/xsl/ConvSpec-Process6-Series.xsl +627 -0
  31. data/vendor/marc2bibframe2/xsl/ConvSpec-Process8-ProvAct.xsl +1021 -0
  32. data/vendor/marc2bibframe2/xsl/conf/abbreviations.xml +13 -0
  33. data/vendor/marc2bibframe2/xsl/conf/code-to-script.xml +399 -0
  34. data/vendor/marc2bibframe2/xsl/conf/codeMaps.xml +723 -0
  35. data/vendor/marc2bibframe2/xsl/conf/exclusions.xml +4 -0
  36. data/vendor/marc2bibframe2/xsl/conf/iso6392-to-1.xml +615 -0
  37. data/vendor/marc2bibframe2/xsl/conf/languageCrosswalk.xml +1503 -0
  38. data/vendor/marc2bibframe2/xsl/conf/map880.xml +175 -0
  39. data/vendor/marc2bibframe2/xsl/conf/scriptCrosswalk.xml +210 -0
  40. data/vendor/marc2bibframe2/xsl/conf/subjectThesaurus.xml +29 -0
  41. data/vendor/marc2bibframe2/xsl/marc2bibframe2.xsl +610 -0
  42. data/vendor/marc2bibframe2/xsl/naco-normalize.xsl +205 -0
  43. data/vendor/marc2bibframe2/xsl/utils.xsl +963 -0
  44. data/vendor/marc2bibframe2/xsl/variables.xsl +108 -0
  45. metadata +68 -1
@@ -0,0 +1,627 @@
1
+ <?xml version='1.0'?>
2
+ <xsl:stylesheet version="1.0" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
3
+ xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:marc="http://www.loc.gov/MARC21/slim"
4
+ xmlns:bf="http://id.loc.gov/ontologies/bibframe/" xmlns:bflc="http://id.loc.gov/ontologies/bflc/"
5
+ xmlns:madsrdf="http://www.loc.gov/mads/rdf/v1#" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
6
+ xmlns:exsl="http://exslt.org/common"
7
+ exclude-result-prefixes="xsl marc">
8
+
9
+
10
+ <!-- Conversion specs for 8XX (and obsolete 4XX) ,490 - Series -->
11
+ <!-- convert 490 unless there's an 8xx with the same issn -->
12
+ <xsl:template match="marc:datafield[
13
+ @tag = '490' or
14
+ (@tag='880' and substring(marc:subfield[@code='6'],1,3)='490' and substring(marc:subfield[@code='6'],4,3)='-00') or
15
+ @tag = '440' or
16
+ (@tag='880' and substring(marc:subfield[@code='6'],1,3)='440' and substring(marc:subfield[@code='6'],4,3)='-00')]" mode="work">
17
+ <xsl:param name="recordid"/>
18
+ <xsl:param name="pPosition" select="position()"/>
19
+ <xsl:param name="serialization" select="'rdfxml'"/>
20
+ <xsl:variable name="vXmlLang">
21
+ <xsl:apply-templates select="." mode="xmllang"/>
22
+ </xsl:variable>
23
+
24
+ <xsl:variable name="hasParallel">
25
+ <xsl:choose>
26
+ <xsl:when
27
+ test="
28
+ count(marc:subfield[@code = 'a']) &gt; 1 and
29
+ (
30
+ substring(marc:subfield[@code = 'a'][1], string-length(marc:subfield[@code = 'a'][1])) = '=' or
31
+ substring(marc:subfield[@code = 'v'][1], string-length(marc:subfield[@code = 'v'][1])) = '='
32
+ )"
33
+ >parallel</xsl:when>
34
+ <xsl:otherwise>separate</xsl:otherwise>
35
+ </xsl:choose>
36
+ </xsl:variable>
37
+
38
+ <xsl:variable name="vXMLLang">
39
+ <xsl:apply-templates select="." mode="xmllang"/>
40
+ </xsl:variable>
41
+
42
+ <xsl:variable name="vOccurrence">
43
+ <xsl:if test="marc:subfield[@code='6'] and not(contains(marc:subfield[@code='6'], '-00'))">
44
+ <xsl:value-of select="substring(substring-after(marc:subfield[@code='6'],'-'),1,2)"/>
45
+ </xsl:if>
46
+ </xsl:variable>
47
+ <xsl:variable name="vRelated880" select="../marc:datafield[@tag='880' and substring(marc:subfield[@code='6'],1,3)='490' and substring(substring-after(marc:subfield[@code='6'],'-'),1,2)=$vOccurrence]" />
48
+ <xsl:variable name="v880XmlLang"><xsl:apply-templates select="$vRelated880" mode="xmllang"/></xsl:variable>
49
+
50
+ <xsl:variable name="gpos" select="1"/>
51
+ <xsl:variable name="pos" select="1"/>
52
+ <xsl:variable name="grouped490InfoPreNS">
53
+ <xsl:apply-templates select="." mode="groupify490">
54
+ <xsl:with-param name="pGPos" select="$gpos" />
55
+ <xsl:with-param name="pPos" select="$pos" />
56
+ <xsl:with-param name="pXmllang" select="$vXMLLang" />
57
+ <xsl:with-param name="pRelated880" select="$vRelated880" />
58
+ <xsl:with-param name="p880Xmllang" select="$v880XmlLang" />
59
+ </xsl:apply-templates>
60
+ </xsl:variable>
61
+ <xsl:variable name="grouped490Info" select="exsl:node-set($grouped490InfoPreNS)"/>
62
+ <!-- <xsl:message><xsl:copy-of select="$grouped490Info"/></xsl:message> -->
63
+
64
+ <!-- Find the group numbers. -->
65
+ <xsl:variable name="tThisDF" select="."/>
66
+ <xsl:variable name="tGroupNums" select="$grouped490Info//@groupNum[not(.=preceding::bf:*/@groupNum[1])]" />
67
+ <xsl:for-each select="$tGroupNums">
68
+ <xsl:variable name="tGNum" select="."/>
69
+ <bf:relation>
70
+ <bf:Relation>
71
+ <bf:relationship>
72
+ <bf:Relationship rdf:about="http://id.loc.gov/vocabulary/relationship/series">
73
+ <rdfs:label>series</rdfs:label>
74
+ </bf:Relationship>
75
+ </bf:relationship>
76
+ <bf:associatedResource>
77
+ <bf:Series>
78
+ <!--
79
+ <xsl:attribute name="rdf:about">
80
+ <xsl:value-of select="$vHubIri"/>
81
+ </xsl:attribute>
82
+ -->
83
+ <bf:status>
84
+ <bf:Status rdf:about="http://id.loc.gov/vocabulary/mstatus/t">
85
+ <rdfs:label>transcribed</rdfs:label>
86
+ </bf:Status>
87
+ </bf:status>
88
+ <xsl:if test="$tThisDF/@ind1='1'">
89
+ <bf:status>
90
+ <bf:Status rdf:about="http://id.loc.gov/vocabulary/mstatus/tr">
91
+ <rdfs:label>traced</rdfs:label>
92
+ </bf:Status>
93
+ </bf:status>
94
+ </xsl:if>
95
+ <xsl:for-each select="$grouped490Info/bf:title[@groupNum=$tGNum] |
96
+ $grouped490Info/bf:identifiedBy[@groupNum=$tGNum]">
97
+ <xsl:element name="{name()}">
98
+ <xsl:copy-of select="child::node()" />
99
+ </xsl:element>
100
+ </xsl:for-each>
101
+ </bf:Series>
102
+ </bf:associatedResource>
103
+ <xsl:for-each select="$grouped490Info/bf:seriesEnumeration[@groupNum=$tGNum]">
104
+ <xsl:element name="{name()}">
105
+ <xsl:if test="@xml:lang">
106
+ <xsl:attribute name="xml:lang"><xsl:value-of select="@xml:lang"/></xsl:attribute>
107
+ </xsl:if>
108
+ <xsl:copy-of select="child::node()" />
109
+ </xsl:element>
110
+ </xsl:for-each>
111
+ <xsl:if test="$tThisDF/marc:subfield[@code='l']">
112
+ <bf:classification>
113
+ <bf:ClassificationLcc>
114
+ <bf:assigner>
115
+ <bf:Agent rdf:about="http://id.loc.gov/vocabulary/organizations/dlc"/>
116
+ </bf:assigner>
117
+ <bf:classificationPortion>
118
+ <xsl:value-of select="$tThisDF/marc:subfield[@code='l'][1]"/>
119
+ </bf:classificationPortion>
120
+ </bf:ClassificationLcc>
121
+ </bf:classification>
122
+ </xsl:if>
123
+ <xsl:if test="$tThisDF/marc:subfield[@code='3']">
124
+ <bflc:appliesTo>
125
+ <bflc:AppliesTo>
126
+ <rdfs:label>
127
+ <xsl:call-template name="tChopPunct">
128
+ <xsl:with-param name="pString" select="$tThisDF/marc:subfield[@code='3'][1]"/>
129
+ </xsl:call-template>
130
+ </rdfs:label>
131
+ </bflc:AppliesTo>
132
+ </bflc:appliesTo>
133
+ </xsl:if>
134
+ </bf:Relation>
135
+ </bf:relation>
136
+ </xsl:for-each>
137
+ </xsl:template>
138
+
139
+ <xsl:template match="marc:datafield" mode="groupify490">
140
+ <xsl:param name="pGPos" />
141
+ <xsl:param name="pPos" />
142
+ <xsl:param name="pXmllang" />
143
+
144
+ <xsl:param name="pRelated880" />
145
+ <xsl:param name="p880Xmllang" />
146
+
147
+ <xsl:variable name="tSF" select="marc:subfield[$pPos]"/>
148
+ <!-- The position should, in theory, be sufficient, but let's match on the code too just to be safe. -->
149
+ <xsl:variable name="tSF880Val">
150
+ <xsl:if test="$pRelated880 != ''">
151
+ <xsl:value-of select="$pRelated880/marc:subfield[$pPos][@code=$tSF/@code]"/>
152
+ </xsl:if>
153
+ </xsl:variable>
154
+
155
+ <!--
156
+ a = title
157
+ v = enumeration
158
+ -->
159
+ <xsl:if test="$tSF/@code='a'">
160
+ <bf:title>
161
+ <xsl:attribute name="groupNum"><xsl:value-of select="$pGPos" /></xsl:attribute>
162
+ <bf:Title>
163
+ <bf:mainTitle>
164
+ <xsl:if test="$pXmllang != ''">
165
+ <xsl:attribute name="xml:lang">
166
+ <xsl:value-of select="$pXmllang"/>
167
+ </xsl:attribute>
168
+ </xsl:if>
169
+ <xsl:call-template name="tChopPunct">
170
+ <xsl:with-param name="pString" select="$tSF"/>
171
+ </xsl:call-template>
172
+ </bf:mainTitle>
173
+ <xsl:if test="$tSF880Val != ''">
174
+ <bf:mainTitle>
175
+ <xsl:if test="$p880Xmllang != ''">
176
+ <xsl:attribute name="xml:lang">
177
+ <xsl:value-of select="$p880Xmllang"/>
178
+ </xsl:attribute>
179
+ </xsl:if>
180
+ <xsl:call-template name="tChopPunct">
181
+ <xsl:with-param name="pString" select="$tSF880Val"/>
182
+ </xsl:call-template>
183
+ </bf:mainTitle>
184
+ </xsl:if>
185
+ <xsl:if test="marc:subfield[$pPos + 1][@code='n']">
186
+ <bf:partNumber>
187
+ <xsl:call-template name="tChopPunct">
188
+ <xsl:with-param name="pString" select="marc:subfield[$pPos + 1][@code='n']"/>
189
+ </xsl:call-template>
190
+ </bf:partNumber>
191
+ </xsl:if>
192
+ <xsl:if test="marc:subfield[$pPos + 2][@code='n']">
193
+ <bf:partNumber>
194
+ <xsl:call-template name="tChopPunct">
195
+ <xsl:with-param name="pString" select="marc:subfield[$pPos + 2][@code='n']"/>
196
+ </xsl:call-template>
197
+ </bf:partNumber>
198
+ </xsl:if><xsl:if test="marc:subfield[$pPos + 1][@code='p']">
199
+ <bf:partName>
200
+ <xsl:call-template name="tChopPunct">
201
+ <xsl:with-param name="pString" select="marc:subfield[$pPos + 1][@code='p']"/>
202
+ </xsl:call-template>
203
+ </bf:partName>
204
+ </xsl:if>
205
+ <xsl:if test="marc:subfield[$pPos + 2][@code='p']">
206
+ <bf:partName>
207
+ <xsl:call-template name="tChopPunct">
208
+ <xsl:with-param name="pString" select="marc:subfield[$pPos + 2][@code='p']"/>
209
+ </xsl:call-template>
210
+ </bf:partName>
211
+ </xsl:if>
212
+ </bf:Title>
213
+ </bf:title>
214
+ </xsl:if>
215
+ <xsl:if test="$tSF/@code='v'">
216
+ <bf:seriesEnumeration>
217
+ <xsl:attribute name="groupNum"><xsl:value-of select="$pGPos" /></xsl:attribute>
218
+ <xsl:if test="$pXmllang != ''">
219
+ <xsl:attribute name="xml:lang">
220
+ <xsl:value-of select="$pXmllang"/>
221
+ </xsl:attribute>
222
+ </xsl:if>
223
+ <xsl:call-template name="tChopPunct">
224
+ <xsl:with-param name="pString" select="$tSF"/>
225
+ </xsl:call-template>
226
+ </bf:seriesEnumeration>
227
+ <xsl:if test="$tSF880Val != ''">
228
+ <bf:seriesEnumeration>
229
+ <xsl:attribute name="groupNum"><xsl:value-of select="$pGPos" /></xsl:attribute>
230
+ <xsl:if test="$p880Xmllang != ''">
231
+ <xsl:attribute name="xml:lang">
232
+ <xsl:value-of select="$p880Xmllang"/>
233
+ </xsl:attribute>
234
+ </xsl:if>
235
+ <xsl:call-template name="tChopPunct">
236
+ <xsl:with-param name="pString" select="$tSF880Val"/>
237
+ </xsl:call-template>
238
+ </bf:seriesEnumeration>
239
+ </xsl:if>
240
+ </xsl:if>
241
+ <xsl:if test="$tSF/@code='x'">
242
+ <bf:identifiedBy>
243
+ <xsl:attribute name="groupNum"><xsl:value-of select="$pGPos" /></xsl:attribute>
244
+ <bf:Issn>
245
+ <rdf:value>
246
+ <xsl:call-template name="tChopPunct">
247
+ <xsl:with-param name="pString" select="$tSF"/>
248
+ </xsl:call-template>
249
+ </rdf:value>
250
+ </bf:Issn>
251
+ </bf:identifiedBy>
252
+ </xsl:if>
253
+ <xsl:if test="$tSF/@code='y'">
254
+ <bf:identifiedBy>
255
+ <xsl:attribute name="groupNum"><xsl:value-of select="$pGPos" /></xsl:attribute>
256
+ <bf:Issn>
257
+ <rdf:value>
258
+ <xsl:call-template name="tChopPunct">
259
+ <xsl:with-param name="pString" select="$tSF"/>
260
+ </xsl:call-template>
261
+ </rdf:value>
262
+ <bf:status>
263
+ <bf:Status
264
+ rdf:about="http://id.loc.gov/vocabulary/mstatus/incorrect">
265
+ <rdfs:label>incorrect</rdfs:label>
266
+ </bf:Status>
267
+ </bf:status>
268
+ </bf:Issn>
269
+ </bf:identifiedBy>
270
+ </xsl:if>
271
+ <xsl:if test="$tSF/@code='z'">
272
+ <bf:identifiedBy>
273
+ <xsl:attribute name="groupNum"><xsl:value-of select="$pGPos" /></xsl:attribute>
274
+ <Issn>
275
+ <rdf:value>
276
+ <xsl:call-template name="tChopPunct">
277
+ <xsl:with-param name="pString" select="$tSF"/>
278
+ </xsl:call-template>
279
+ </rdf:value>
280
+ <bf:status>
281
+ <bf:Status rdf:about="http://id.loc.gov/vocabulary/mstatus/cancinv">
282
+ <rdfs:label>canceled</rdfs:label>
283
+ </bf:Status>
284
+ </bf:status>
285
+ </Issn>
286
+ </bf:identifiedBy>
287
+ </xsl:if>
288
+
289
+ <xsl:variable name="next_gpos" select="$pGPos + 1"/>
290
+ <xsl:variable name="next_pos" select="$pPos + 1"/>
291
+
292
+ <xsl:choose>
293
+ <xsl:when test="$tSF/@code = '6'">
294
+ <xsl:apply-templates select="." mode="groupify490">
295
+ <xsl:with-param name="pGPos" select="$pGPos" />
296
+ <xsl:with-param name="pPos" select="$next_pos" />
297
+ <xsl:with-param name="pXmllang" select="$pXmllang" />
298
+ <xsl:with-param name="pRelated880" select="$pRelated880" />
299
+ <xsl:with-param name="p880Xmllang" select="$p880Xmllang" />
300
+ </xsl:apply-templates>
301
+ </xsl:when>
302
+ <!-- This subfield is the end of a parallel title. Start a new group. -->
303
+ <xsl:when test="substring($tSF, string-length($tSF))='='">
304
+ <xsl:apply-templates select="." mode="groupify490">
305
+ <xsl:with-param name="pGPos" select="$next_gpos" />
306
+ <xsl:with-param name="pPos" select="$next_pos" />
307
+ <xsl:with-param name="pXmllang" select="$pXmllang" />
308
+ </xsl:apply-templates>
309
+ </xsl:when>
310
+ <!-- The next subfield is an 'a' and this subfield is not. Start a new group. -->
311
+ <xsl:when test="$tSF/@code != 'a' and marc:subfield[$next_pos]/@code='a'">
312
+ <xsl:apply-templates select="." mode="groupify490">
313
+ <xsl:with-param name="pGPos" select="$next_gpos" />
314
+ <xsl:with-param name="pPos" select="$next_pos" />
315
+ <xsl:with-param name="pXmllang" select="$pXmllang" />
316
+ </xsl:apply-templates>
317
+ </xsl:when>
318
+ <xsl:when test="marc:subfield[$next_pos]">
319
+ <xsl:apply-templates select="." mode="groupify490">
320
+ <xsl:with-param name="pGPos" select="$pGPos" />
321
+ <xsl:with-param name="pPos" select="$next_pos" />
322
+ <xsl:with-param name="pXmllang" select="$pXmllang" />
323
+ <xsl:with-param name="pRelated880" select="$pRelated880" />
324
+ <xsl:with-param name="p880Xmllang" select="$p880Xmllang" />
325
+ </xsl:apply-templates>
326
+ </xsl:when>
327
+ </xsl:choose>
328
+ </xsl:template>
329
+
330
+
331
+ <xsl:template
332
+ match="
333
+ marc:datafield[@tag = '800' or (@tag = '880' and substring(marc:subfield[@code = '6'], 1, 3) = '800')] |
334
+ marc:datafield[@tag = '810' or (@tag = '880' and substring(marc:subfield[@code = '6'], 1, 3) = '810')] |
335
+ marc:datafield[@tag = '811' or (@tag = '880' and substring(marc:subfield[@code = '6'], 1, 3) = '811')] |
336
+ marc:datafield[@tag = '830' or (@tag = '880' and substring(marc:subfield[@code = '6'], 1, 3) = '830')] |
337
+ marc:datafield[@tag = '400' or @tag = '410' or @tag = '411']"
338
+ mode="work">
339
+ <xsl:param name="recordid"/>
340
+ <xsl:param name="pPosition" select="position()"/>
341
+ <xsl:param name="serialization" select="'rdfxml'"/>
342
+ <xsl:param name="pHasItem" select="false()"/>
343
+ <!-- note special $5 processing for LoC below -->
344
+ <xsl:if test="$pHasItem or not($localfields and marc:subfield[@code = '5'])">
345
+ <xsl:variable name="vCurrentPos">
346
+ <xsl:choose>
347
+ <xsl:when test="substring(@tag, 1, 1) = '8'">
348
+ <xsl:value-of
349
+ select="count(preceding-sibling::marc:datafield[@tag = '800' or @tag = '810' or @tag = '811' or @tag = '830' or (@tag = '880' and (substring(marc:subfield[@code = '6'], 1, 3) = '800' or substring(marc:subfield[@code = '6'], 1, 3) = '810' or substring(marc:subfield[@code = '6'], 1, 3) = '811' or substring(marc:subfield[@code = '6'], 1, 3) = '830') and substring(substring-after(marc:subfield[@code = '6'], '-'), 1, 2) = '00')]) + 1"
350
+ />
351
+ </xsl:when>
352
+ </xsl:choose>
353
+ </xsl:variable>
354
+ <xsl:apply-templates select="." mode="work8XX">
355
+ <xsl:with-param name="recordid" select="$recordid"/>
356
+ <xsl:with-param name="serialization" select="$serialization"/>
357
+ <xsl:with-param name="pCurrentPos" select="$vCurrentPos"/>
358
+ <xsl:with-param name="pPosition" select="$pPosition"/>
359
+ </xsl:apply-templates>
360
+ </xsl:if>
361
+ </xsl:template>
362
+
363
+ <xsl:template match="marc:datafield" mode="work8XX">
364
+ <xsl:param name="recordid"/>
365
+ <xsl:param name="serialization" select="'rdfxml'"/>
366
+ <xsl:param name="pCurrentPos"/>
367
+ <xsl:param name="pPosition" select="position()"/>
368
+ <xsl:variable name="vXmlLang">
369
+ <xsl:apply-templates select="." mode="xmllang"/>
370
+ </xsl:variable>
371
+ <xsl:variable name="vTag">
372
+ <xsl:choose>
373
+ <xsl:when test="@tag = '880'">
374
+ <xsl:value-of select="substring(marc:subfield[@code = '6'], 1, 3)"/>
375
+ </xsl:when>
376
+ <xsl:otherwise>
377
+ <xsl:value-of select="@tag"/>
378
+ </xsl:otherwise>
379
+ </xsl:choose>
380
+ </xsl:variable>
381
+ <xsl:variable name="vHubIri">
382
+ <xsl:choose>
383
+ <xsl:when test="($vTag = '830' or $vTag = '440') and marc:subfield[@code='1']">
384
+ <xsl:apply-templates mode="generateUriFrom1" select=".">
385
+ <xsl:with-param name="pDefaultUri"><xsl:value-of select="$recordid"/>#Hub<xsl:value-of select="@tag"/>-<xsl:value-of select="$pPosition"/></xsl:with-param>
386
+ <xsl:with-param name="pEntity">bf:Hub</xsl:with-param>
387
+ </xsl:apply-templates>
388
+ </xsl:when>
389
+ <xsl:otherwise>
390
+ <xsl:apply-templates mode="generateUri" select=".">
391
+ <xsl:with-param name="pDefaultUri"><xsl:value-of select="$recordid"/>#Hub<xsl:value-of select="@tag"/>-<xsl:value-of select="$pPosition"/></xsl:with-param>
392
+ <xsl:with-param name="pEntity">bf:Hub</xsl:with-param>
393
+ </xsl:apply-templates>
394
+ </xsl:otherwise>
395
+ </xsl:choose>
396
+ </xsl:variable>
397
+ <xsl:variable name="agentiri">
398
+ <xsl:choose>
399
+ <xsl:when test="($vTag != '830' and $vTag != '440') and marc:subfield[@code='1']">
400
+ <xsl:apply-templates mode="generateUriFrom1" select=".">
401
+ <xsl:with-param name="pDefaultUri"><xsl:value-of select="$recordid"/>#Agent<xsl:value-of select="@tag"/>-<xsl:value-of select="$pPosition"/></xsl:with-param>
402
+ <xsl:with-param name="pEntity">bf:Agent</xsl:with-param>
403
+ </xsl:apply-templates>
404
+ </xsl:when>
405
+ <xsl:when test="($vTag != '830' and $vTag != '440') and marc:subfield[@code='0'][contains(text(),'id.loc.gov/authorities/names/')]">
406
+ <xsl:apply-templates mode="generateUriFrom1" select=".">
407
+ <xsl:with-param name="pDefaultUri"><xsl:value-of select="$recordid"/>#Agent<xsl:value-of select="@tag"/>-<xsl:value-of select="$pPosition"/></xsl:with-param>
408
+ <xsl:with-param name="pEntity">bf:Agent</xsl:with-param>
409
+ </xsl:apply-templates>
410
+ </xsl:when>
411
+ <xsl:otherwise>
412
+ <xsl:apply-templates mode="generateUri" select=".">
413
+ <xsl:with-param name="pDefaultUri"><xsl:value-of select="$recordid"/>#Agent<xsl:value-of select="@tag"/>-<xsl:value-of select="$pPosition"/></xsl:with-param>
414
+ <xsl:with-param name="pEntity">bf:Agent</xsl:with-param>
415
+ </xsl:apply-templates>
416
+ </xsl:otherwise>
417
+ </xsl:choose>
418
+ </xsl:variable>
419
+ <!-- <xsl:variable name="vLabel">
420
+ <xsl:apply-templates mode="concat-nodes-space"
421
+ select="marc:subfield[not(contains('hvwx012345678', @code))]"/>
422
+ </xsl:variable>-->
423
+
424
+ <xsl:variable name="vOccurrence">
425
+ <xsl:if test="marc:subfield[@code='6'] and not(contains(marc:subfield[@code='6'], '-00'))">
426
+ <xsl:value-of select="substring(substring-after(marc:subfield[@code='6'],'-'),1,2)"/>
427
+ </xsl:if>
428
+ </xsl:variable>
429
+ <xsl:variable name="vRelated880" select="../marc:datafield[@tag='880' and substring(marc:subfield[@code='6'],1,3)=$vTag and substring(substring-after(marc:subfield[@code='6'],'-'),1,2)=$vOccurrence]" />
430
+ <xsl:variable name="v880XmlLang"><xsl:apply-templates select="$vRelated880" mode="xmllang"/></xsl:variable>
431
+
432
+ <xsl:choose>
433
+ <xsl:when test="$serialization = 'rdfxml'">
434
+ <bf:relation>
435
+ <bf:Relation>
436
+ <bf:relationship>
437
+ <bf:Relationship rdf:about="http://id.loc.gov/vocabulary/relationship/series">
438
+ <rdfs:label>series</rdfs:label>
439
+ </bf:Relationship>
440
+ </bf:relationship>
441
+ <bf:associatedResource>
442
+ <bf:Hub>
443
+ <xsl:attribute name="rdf:about">
444
+ <xsl:value-of select="$vHubIri"/>
445
+ </xsl:attribute>
446
+ <rdf:type rdf:resource="http://id.loc.gov/ontologies/bibframe/Series"/>
447
+ <!--see if this works for 830, and 8xx both names and titles eg-->
448
+ <xsl:choose>
449
+ <xsl:when test="$vTag = '830' or $vTag = '440'">
450
+ <xsl:apply-templates mode="hubUnifTitle" select=".">
451
+ <xsl:with-param name="serialization" select="$serialization"/>
452
+ <!-- <xsl:with-param name="pLabel" select="marc:subfield[@code='a']"/> -->
453
+ </xsl:apply-templates>
454
+ </xsl:when>
455
+ <xsl:otherwise>
456
+ <xsl:apply-templates mode="workName" select=".">
457
+ <xsl:with-param name="agentiri" select="$agentiri"/>
458
+ <xsl:with-param name="serialization" select="$serialization"/>
459
+ </xsl:apply-templates>
460
+ </xsl:otherwise>
461
+ </xsl:choose>
462
+
463
+ <xsl:for-each select="marc:subfield[@code = 'w']">
464
+ <xsl:variable name="vIdClass">
465
+ <xsl:choose>
466
+ <xsl:when test="starts-with(., '(DLC)')">bf:Lccn</xsl:when>
467
+ <xsl:otherwise>bf:Identifier</xsl:otherwise>
468
+ </xsl:choose>
469
+ </xsl:variable>
470
+ <xsl:apply-templates mode="subfield0orw" select=".">
471
+ <xsl:with-param name="serialization" select="$serialization"/>
472
+ <xsl:with-param name="pIdClass" select="$vIdClass"/>
473
+ </xsl:apply-templates>
474
+ </xsl:for-each>
475
+ <xsl:for-each select="marc:subfield[@code = 'x']">
476
+ <bf:identifiedBy>
477
+ <bf:Issn>
478
+ <rdf:value>
479
+ <xsl:call-template name="tChopPunct">
480
+ <xsl:with-param name="pString" select="."/>
481
+ </xsl:call-template>
482
+ </rdf:value>
483
+ </bf:Issn>
484
+ </bf:identifiedBy>
485
+ </xsl:for-each>
486
+ <xsl:for-each select="marc:subfield[@code = 'y']">
487
+ <bf:identifiedBy>
488
+ <bf:Issn>
489
+ <rdf:value>
490
+ <xsl:call-template name="tChopPunct">
491
+ <xsl:with-param name="pString" select="."/>
492
+ </xsl:call-template>
493
+ </rdf:value>
494
+ <bf:status>
495
+ <bf:Status
496
+ rdf:about="http://id.loc.gov/vocabulary/mstatus/incorrect">
497
+ <rdfs:label>incorrect</rdfs:label>
498
+ </bf:Status>
499
+ </bf:status>
500
+ </bf:Issn>
501
+ </bf:identifiedBy>
502
+ </xsl:for-each>
503
+ <xsl:for-each select="marc:subfield[@code = 'z']">
504
+ <bf:identifiedBy>
505
+ <bf:Issn>
506
+ <rdf:value>
507
+ <xsl:call-template name="tChopPunct">
508
+ <xsl:with-param name="pString" select="."/>
509
+ </xsl:call-template>
510
+ </rdf:value>
511
+ <bf:status>
512
+ <bf:Status rdf:about="http://id.loc.gov/vocabulary/mstatus/cancinv">
513
+ <rdfs:label>canceled</rdfs:label>
514
+ </bf:Status>
515
+ </bf:status>
516
+ </bf:Issn>
517
+ </bf:identifiedBy>
518
+ </xsl:for-each>
519
+
520
+ <!-- $3 processed by hubUnifTitle template -->
521
+ <xsl:apply-templates mode="subfield5" select="marc:subfield[@code = '5']">
522
+ <xsl:with-param name="serialization" select="$serialization"/>
523
+ </xsl:apply-templates>
524
+ <xsl:apply-templates mode="subfield7" select="marc:subfield[@code = '7']">
525
+ <xsl:with-param name="serialization" select="$serialization"/>
526
+ </xsl:apply-templates>
527
+ </bf:Hub>
528
+ </bf:associatedResource>
529
+ <xsl:for-each select="marc:subfield[@code = 'v']">
530
+ <bf:seriesEnumeration>
531
+ <xsl:value-of select="."/>
532
+ </bf:seriesEnumeration>
533
+ </xsl:for-each>
534
+ <xsl:for-each select="$vRelated880/marc:subfield[@code='v']">
535
+ <bf:seriesEnumeration>
536
+ <xsl:if test="$v880XmlLang != ''">
537
+ <xsl:attribute name="xml:lang"><xsl:value-of select="$v880XmlLang"/></xsl:attribute>
538
+ </xsl:if>
539
+ <xsl:value-of select="."/>
540
+ </bf:seriesEnumeration>
541
+ </xsl:for-each>
542
+
543
+ </bf:Relation>
544
+ </bf:relation>
545
+
546
+ </xsl:when>
547
+ </xsl:choose>
548
+ </xsl:template>
549
+
550
+ <!--
551
+ extract ISSN for series from matching 490
552
+ if there is no matching 490 (or the matching 490 has no $x),
553
+ return empty string
554
+ 2022-07-22 No longer matching up 490/8xx.
555
+ -->
556
+ <!--<xsl:template name="tIdentifier490">
557
+ <xsl:param name="pCurrentPos" select="1"/>
558
+ <xsl:param name="pLastPos"/>
559
+ <xsl:param name="pCompositePos" select="1"/>
560
+ <xsl:param name="pCode" />
561
+
562
+ <xsl:if
563
+ test="../marc:datafield[@tag = '490' and @ind1 = '1'][$pCurrentPos]/marc:subfield[@code = 'a']">
564
+ <xsl:choose>
565
+ <xsl:when test="$pCompositePos &lt;= $pLastPos">
566
+ <xsl:variable name="vParallel">
567
+ <xsl:choose>
568
+ <xsl:when
569
+ test="
570
+ substring(../marc:datafield[((@tag = '880' and substring(marc:subfield[@code = '6'], 1, 3) = '490') or (@tag = '490' and not(marc:subfield[@code = '6']))) and @ind1 = '1'][$pCurrentPos]/marc:subfield[@code = 'a'][1], string-length(../marc:datafield[@tag = '490' and @ind1 = '1'][$pCurrentPos]/marc:subfield[@code = 'a'][1])) = '=' or
571
+ substring(../marc:datafield[((@tag = '880' and substring(marc:subfield[@code = '6'], 1, 3) = '490') or (@tag = '490' and not(marc:subfield[@code = '6']))) and @ind1 = '1'][$pCurrentPos]/marc:subfield[@code = 'v'][1], string-length(../marc:datafield[((@tag = '880' and substring(marc:subfield[@code = '6'], 1, 3) = '490') or (@tag = '490' and not(marc:subfield[@code = '6']))) and @ind1 = '1'][$pCurrentPos]/marc:subfield[@code = 'v'][1])) = '='">
572
+ <xsl:text>parallel</xsl:text>
573
+ </xsl:when>
574
+ </xsl:choose>
575
+ </xsl:variable>
576
+ <xsl:choose>
577
+ <xsl:when test="$vParallel != ''">
578
+ <xsl:choose>
579
+ <xsl:when test="$pCompositePos = $pLastPos">
580
+ <xsl:call-template name="tChopPunct">
581
+ <xsl:with-param name="pString"
582
+ select="../marc:datafield[((@tag = '880' and substring(marc:subfield[@code = '6'], 1, 3) = '490') or (@tag = '490' and not(marc:subfield[@code = '6']))) and @ind1 = '1'][$pCurrentPos]/marc:subfield[@code = 'x'][1]"
583
+ />
584
+ </xsl:call-template>
585
+ </xsl:when>
586
+ <xsl:otherwise>
587
+ <xsl:call-template name="tIdentifier490">
588
+ <xsl:with-param name="pCurrentPos" select="$pCurrentPos + 1"/>
589
+ <xsl:with-param name="pLastPos" select="$pLastPos"/>
590
+ <xsl:with-param name="pCompositePos" select="$pCompositePos + 1"/>
591
+ <xsl:with-param name="pCode"><xsl:value-of select="$pCode"/></xsl:with-param>
592
+ </xsl:call-template>
593
+ </xsl:otherwise>
594
+ </xsl:choose>
595
+ </xsl:when>
596
+ <xsl:otherwise>
597
+ <xsl:for-each
598
+ select="../marc:datafield[((@tag = '880' and substring(marc:subfield[@code = '6'], 1, 3) = '490') or (@tag = '490' and not(marc:subfield[@code = '6']))) and @ind1 = '1'][$pCurrentPos]/marc:subfield[@code = 'a']">
599
+ <xsl:variable name="vCurrentNode" select="generate-id(.)"/>
600
+ <xsl:if test="$pCompositePos + position() - 1 = $pLastPos">
601
+ <xsl:call-template name="tChopPunct">
602
+ <xsl:with-param name="pString"
603
+ select="following-sibling::marc:subfield[@code = $pCode and generate-id(preceding-sibling::marc:subfield[@code = 'a'][1]) = $vCurrentNode]"
604
+ />
605
+ </xsl:call-template>
606
+ </xsl:if>
607
+ </xsl:for-each>
608
+ <xsl:if
609
+ test="$pCompositePos + count(../marc:datafield[((@tag = '880' and substring(marc:subfield[@code = '6'], 1, 3) = '490') or (@tag = '490' and not(marc:subfield[@code = '6']))) and @ind1 = '1'][$pCurrentPos]/marc:subfield[@code = 'a']) &lt; $pLastPos">
610
+ <xsl:call-template name="tIdentifier490">
611
+ <xsl:with-param name="pCurrentPos" select="$pCurrentPos + 1"/>
612
+ <xsl:with-param name="pLastPos" select="$pLastPos"/>
613
+ <xsl:with-param name="pCompositePos"
614
+ select="$pCompositePos + count(../marc:datafield[((@tag = '880' and substring(marc:subfield[@code = '6'], 1, 3) = '490') or (@tag = '490' and not(marc:subfield[@code = '6']))) and @ind1 = '1'][$pCurrentPos]/marc:subfield[@code = 'a'])"
615
+ />
616
+ <xsl:with-param name="pCode"><xsl:value-of select="$pCode"/></xsl:with-param>
617
+ </xsl:call-template>
618
+ </xsl:if>
619
+ </xsl:otherwise>
620
+ </xsl:choose>
621
+ </xsl:when>
622
+ </xsl:choose>
623
+ </xsl:if>
624
+ </xsl:template>
625
+ -->
626
+
627
+ </xsl:stylesheet>