Last active
November 16, 2024 10:55
-
-
Save gregoriopellegrino/764d9e8689b1a54908da67fd493456e4 to your computer and use it in GitHub Desktop.
XSLT to transform ONIX for Books metadata into EPUB metadata
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dc="http://purl.org/dc/elements/1.1/" version="1.0"> | |
<xsl:output method="xml" indent="yes" /> | |
<xsl:template match="Header" /> | |
<xsl:template match="Product"> | |
<!-- dc:identifier https://www.w3.org/TR/epub-33/#sec-opf-dcidentifier --> | |
<dc:identifier id="bookid"> | |
<xsl:value-of select="concat('urn:isbn:', ProductIdentifier[ProductIDType='15']/IDValue)" /> | |
</dc:identifier> | |
<meta property="identifier-type" refines="#bookid" scheme="onix:codelist5">15</meta> | |
<!-- dc:title https://www.w3.org/publishing/epub3/epub-packages.html#sec-opf-dctitle --> | |
<dc:title id="main-title"> | |
<xsl:value-of select="normalize-space(concat(DescriptiveDetail/TitleDetail[TitleType = '01']/TitleElement[TitleElementLevel = '01']/TitleText/text(), ' ', DescriptiveDetail/TitleDetail[TitleType = '01']/TitleElement[TitleElementLevel = '01']/TitlePrefix/text(), ' ', DescriptiveDetail/TitleDetail[TitleType = '01']/TitleElement[TitleElementLevel = '01']/TitleWithoutPrefix/text()))" /> | |
</dc:title> | |
<meta property="title-type" refines="#main-title">main</meta> | |
<!-- dc:date https://www.w3.org/publishing/epub3/epub-packages.html#sec-opf-dcdate --> | |
<!-- I don't set the field dc:date because I start from an ONIX made for the paper book, so the date of publication does not coincide --> | |
<!-- dc:creator https://www.w3.org/publishing/epub3/epub-packages.html#sec-opf-dccreator --> | |
<xsl:for-each select="DescriptiveDetail/Contributor[not(UnnamedPersons) and ((ContributorRole = 'A01') or (ContributorRole = 'B01') or (ContributorRole = 'A12'))]"> | |
<dc:creator id="{concat('creator',position())}"> | |
<xsl:value-of select="PersonName" /> | |
</dc:creator> | |
<!-- MARC relators roles https://www.loc.gov/marc/relators/relaterm.html --> | |
<!-- based on https://www.oclc.org/content/dam/research/publications/library/2012/2012-04.pdf --> | |
<meta refines="{concat('#creator',position())}" property="role" scheme="marc:relators"> | |
<xsl:choose> | |
<xsl:when test="ContributorRole = 'A01'">aut</xsl:when> | |
<xsl:when test="ContributorRole = 'A12'">ill</xsl:when> | |
<xsl:when test="ContributorRole = 'B01'">edt</xsl:when> | |
</xsl:choose> | |
</meta> | |
<meta refines="{concat('#creator',position())}" property="file-as"> | |
<xsl:value-of select="PersonNameInverted" /> | |
</meta> | |
</xsl:for-each> | |
<!-- dc:contributor https://www.w3.org/publishing/epub3/epub-packages.html#sec-opf-dccontributor --> | |
<xsl:for-each select="DescriptiveDetail/Contributor[not(UnnamedPersons) and (ContributorRole != 'A01') and (ContributorRole != 'B01') and (ContributorRole != 'A12')]"> | |
<dc:contributor id="{concat('contributor',position())}"> | |
<xsl:value-of select="PersonName" /> | |
</dc:contributor> | |
<!-- MARC relators roles https://www.loc.gov/marc/relators/relaterm.html --> | |
<!-- based on https://www.oclc.org/content/dam/research/publications/library/2012/2012-04.pdf --> | |
<meta refines="{concat('#contributor',position())}" property="role" scheme="marc:relators"> | |
<xsl:choose> | |
<xsl:when test="ContributorRole = 'A01'">aut</xsl:when> | |
<xsl:when test="ContributorRole = 'A02'">ctb</xsl:when> | |
<xsl:when test="ContributorRole = 'A03'">aus</xsl:when> | |
<xsl:when test="ContributorRole = 'A04'">lbt</xsl:when> | |
<xsl:when test="ContributorRole = 'A05'">lyr</xsl:when> | |
<xsl:when test="ContributorRole = 'A06'">cmp</xsl:when> | |
<xsl:when test="ContributorRole = 'A07'">art</xsl:when> | |
<xsl:when test="ContributorRole = 'A08'">pht</xsl:when> | |
<xsl:when test="ContributorRole = 'A09'">cre</xsl:when> | |
<xsl:when test="ContributorRole = 'A10'">cre</xsl:when> | |
<xsl:when test="ContributorRole = 'A11'">dsr</xsl:when> | |
<xsl:when test="ContributorRole = 'A12'">ill</xsl:when> | |
<xsl:when test="ContributorRole = 'A13'">pht</xsl:when> | |
<xsl:when test="ContributorRole = 'A14'">ctb</xsl:when> | |
<xsl:when test="ContributorRole = 'A15'">aui</xsl:when> | |
<xsl:when test="ContributorRole = 'A16'">aui</xsl:when> | |
<xsl:when test="ContributorRole = 'A17'">ctb</xsl:when> | |
<xsl:when test="ContributorRole = 'A18'">ctb</xsl:when> | |
<xsl:when test="ContributorRole = 'A19'">aft</xsl:when> | |
<xsl:when test="ContributorRole = 'A20'">ctb</xsl:when> | |
<xsl:when test="ContributorRole = 'A21'">cwt</xsl:when> | |
<xsl:when test="ContributorRole = 'A22'">aft</xsl:when> | |
<xsl:when test="ContributorRole = 'A23'">aui</xsl:when> | |
<xsl:when test="ContributorRole = 'A24'">aui</xsl:when> | |
<xsl:when test="ContributorRole = 'A25'">ctb</xsl:when> | |
<xsl:when test="ContributorRole = 'A27'">ctb</xsl:when> | |
<xsl:when test="ContributorRole = 'A29'">aui</xsl:when> | |
<xsl:when test="ContributorRole = 'A30'">prg</xsl:when> | |
<xsl:when test="ContributorRole = 'A31'">lyr</xsl:when> | |
<xsl:when test="ContributorRole = 'A32'">ctb</xsl:when> | |
<xsl:when test="ContributorRole = 'A33'">clb</xsl:when> | |
<xsl:when test="ContributorRole = 'A34'">ctb</xsl:when> | |
<xsl:when test="ContributorRole = 'A35'">ill</xsl:when> | |
<xsl:when test="ContributorRole = 'A36'">cov</xsl:when> | |
<xsl:when test="ContributorRole = 'A37'">ant</xsl:when> | |
<xsl:when test="ContributorRole = 'A38'">aut</xsl:when> | |
<xsl:when test="ContributorRole = 'A39'">ctg</xsl:when> | |
<xsl:when test="ContributorRole = 'A40'">ill</xsl:when> | |
<xsl:when test="ContributorRole = 'A43'">ivr</xsl:when> | |
<xsl:when test="ContributorRole = 'A44'">ive</xsl:when> | |
<xsl:when test="ContributorRole = 'A99'">cre</xsl:when> | |
<xsl:when test="ContributorRole = 'B01'">edt</xsl:when> | |
<xsl:when test="ContributorRole = 'B02'">edt</xsl:when> | |
<xsl:when test="ContributorRole = 'B03'">nrt</xsl:when> | |
<xsl:when test="ContributorRole = 'B04'">edt</xsl:when> | |
<xsl:when test="ContributorRole = 'B05'">adp</xsl:when> | |
<xsl:when test="ContributorRole = 'B06'">trl</xsl:when> | |
<xsl:when test="ContributorRole = 'B07'">nrt</xsl:when> | |
<xsl:when test="ContributorRole = 'B08'">trl</xsl:when> | |
<xsl:when test="ContributorRole = 'B09'">edt</xsl:when> | |
<xsl:when test="ContributorRole = 'B10'">trl</xsl:when> | |
<xsl:when test="ContributorRole = 'B11'">pbd</xsl:when> | |
<xsl:when test="ContributorRole = 'B12'">edt</xsl:when> | |
<xsl:when test="ContributorRole = 'B13'">edt</xsl:when> | |
<xsl:when test="ContributorRole = 'B14'">edt</xsl:when> | |
<xsl:when test="ContributorRole = 'B15'">edt</xsl:when> | |
<xsl:when test="ContributorRole = 'B16'">edt</xsl:when> | |
<xsl:when test="ContributorRole = 'B18'">pbl</xsl:when> | |
<xsl:when test="ContributorRole = 'B19'">edt</xsl:when> | |
<xsl:when test="ContributorRole = 'B20'">edt</xsl:when> | |
<xsl:when test="ContributorRole = 'B21'">edt</xsl:when> | |
<xsl:when test="ContributorRole = 'B23'">edt</xsl:when> | |
<xsl:when test="ContributorRole = 'B24'">edt</xsl:when> | |
<xsl:when test="ContributorRole = 'B25'">arr</xsl:when> | |
<xsl:when test="ContributorRole = 'B99'">adp</xsl:when> | |
<xsl:when test="ContributorRole = 'C01'">com</xsl:when> | |
<xsl:when test="ContributorRole = 'C02'">com</xsl:when> | |
<xsl:when test="ContributorRole = 'C99'">com</xsl:when> | |
<xsl:when test="ContributorRole = 'D01'">pro</xsl:when> | |
<xsl:when test="ContributorRole = 'D02'">drt</xsl:when> | |
<xsl:when test="ContributorRole = 'D03'">cnd</xsl:when> | |
<xsl:when test="ContributorRole = 'D99'">drt</xsl:when> | |
<xsl:when test="ContributorRole = 'E01'">act</xsl:when> | |
<xsl:when test="ContributorRole = 'E02'">dnc</xsl:when> | |
<xsl:when test="ContributorRole = 'E03'">nrt</xsl:when> | |
<xsl:when test="ContributorRole = 'E04'">cmm</xsl:when> | |
<xsl:when test="ContributorRole = 'E05'">voc</xsl:when> | |
<xsl:when test="ContributorRole = 'E06'">itr</xsl:when> | |
<xsl:when test="ContributorRole = 'E07'">nrt</xsl:when> | |
<xsl:when test="ContributorRole = 'E08'">prf</xsl:when> | |
<xsl:when test="ContributorRole = 'E99'">prf</xsl:when> | |
<xsl:when test="ContributorRole = 'F01'">pht</xsl:when> | |
</xsl:choose> | |
</meta> | |
<meta refines="#creator" property="file-as"> | |
<xsl:value-of select="PersonNameInverted" /> | |
</meta> | |
</xsl:for-each> | |
<!-- dc:description https://www.w3.org/publishing/epub3/epub-packages.html#sec-opf-dcmes-optional-def --> | |
<dc:description> | |
<xsl:value-of select="CollateralDetail/TextContent[TextType='02']/Text[@language='ita']" /> | |
</dc:description> | |
<!-- dc:publisher https://www.w3.org/publishing/epub3/epub-packages.html#sec-opf-dcmes-optional-def --> | |
<dc:publisher> | |
<xsl:value-of select="PublishingDetail/Publisher/PublisherName" /> | |
</dc:publisher> | |
<!-- dc:rights https://www.w3.org/publishing/epub3/epub-packages.html#sec-opf-dcmes-optional-def --> | |
<dc:rights> | |
<xsl:value-of select="concat('© ', PublishingDetail/Publisher[PublishingRole='01']/PublisherName, ' ', PublishingDetail/Publisher/Website[WebsiteRole='01'][1]/WebsiteLink)" /> | |
</dc:rights> | |
<!-- dc:source https://www.w3.org/publishing/epub3/epub-packages.html#sec-opf-dcmes-optional-def --> | |
<dc:source id="paper-version"> | |
<xsl:value-of select="concat('urn:isbn:', RelatedMaterial/RelatedProduct[ProductRelationCode='13']/ProductIdentifier[ProductIDType='15']/IDValue)" /> | |
</dc:source> | |
<meta property="identifier-type" refines="#paper-version" scheme="onix:codelist5">15</meta> | |
<!-- dc:subject https://www.w3.org/publishing/epub3/epub-packages.html#sec-opf-dcsubject --> | |
<xsl:for-each select="tokenize(DescriptiveDetail/Subject[SubjectSchemeIdentifier='20']/SubjectHeadingText, ';')"> | |
<dc:subject> | |
<xsl:value-of select="normalize-space(.)" /> | |
</dc:subject> | |
</xsl:for-each> | |
</xsl:template> | |
</xsl:stylesheet> |
Oh and I just noticed that dc:source
(line 128) doesn’t generate a <meta refine>
?
@jenstroeger: thanks, fixed!
Oh and I just noticed that
dc:source
(line 128) doesn’t generate a<meta refine>
?
I don't think it is required: https://w3c.github.io/publ-epub-revision/epub32/spec/epub-packages.html#sec-source-of
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi @gregoriopellegrino, a few thoughts on the code…
in lines 51–52 are duplicated. The
select
in line 130I think is too strict assuming a space
'; '
so instead I’d considerAnd lastly, extracting a description in line 119
here will extract potential
<![CDATA[<p>A description</p>]]>
or escaped string"<p>A description</p>
or even an XHTML tree<p>A description</p>
. I’m not sure what XSLT processor you use, but there seems no easy way to handle this in plain XSLT of any version.