MusicXML 4.0 >
File Listings >
to30.xsl
to30.xsl
<?xml version="1.0" encoding="UTF-8"?>
<!--
MusicXML to30.xsl stylesheet
Version 4.0
Copyright © 2004-2021 the Contributors to the MusicXML
Specification, published by the W3C Music Notation Community
Group under the W3C Community Final Specification Agreement
(FSA):
https://www.w3.org/community/about/agreements/final/
A human-readable summary is available:
https://www.w3.org/community/about/agreements/fsa-deed/
-->
<!--
To30.xsl converts from MusicXML 3.1 to 3.0 for
compatibility with older products.
-->
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--
XML output, with a DOCTYPE referring the partwise DTD.
Here we use the full Internet URL.
-->
<xsl:output method="xml" indent="yes" encoding="UTF-8"
omit-xml-declaration="no" standalone="no"
doctype-system="http://www.musicxml.org/dtds/partwise.dtd"
doctype-public="-//Recordare//DTD MusicXML 3.0 Partwise//EN"/>
<!--
For the root, only look for score-partwise. Anything else
as a root element gets ignored.
-->
<xsl:template match="/">
<xsl:apply-templates select="./score-partwise"/>
</xsl:template>
<!--
Transformations that remove post-3.0 elements and
attributes.
-->
<!-- Additions in note.mod -->
<!--
Earlier versions of MusicXML allow notes to have a
grace or cue element, but not both. Remove any cue
element that follows a grace element.
-->
<xsl:template
match="note/cue[preceding-sibling::grace]"/>
<!-- Remove new elements. -->
<xsl:template
match="arrowhead | brass-bend | flip | golpe |
half-muted | harmon-mute | haydn |
inverted-vertical-turn | open |
smear | soft-accent"/>
<!-- Remove new id attributes. -->
<xsl:template
match="note/@id | beam/@id |
notations/@id | tied/@id |
slur/@id | tuplet/@id |
glissando/@id | slide/@id |
other-notation/@id | ornaments/@id |
accidental-mark/@id | technical/@id |
articulations/@id | arpeggiate/@id |
non-arpeggiate/@id | lyric/@id |
figured-bass/@id"/>
<!--
Remove accidental and accidental-mark elements with
the new accidental values.
-->
<xsl:template
match="accidental[. = 'double-sharp-down' or
. = 'double-sharp-up' or . = 'flat-flat-down' or
. = 'flat-flat-up' or . = 'arrow-down' or
. = 'arrow-up' or . = 'other']"/>
<xsl:template
match="accidental-mark[. = 'double-sharp-down' or
. = 'double-sharp-up' or . = 'flat-flat-down' or
. = 'flat-flat-up' or . = 'arrow-down' or
. = 'arrow-up' or . = 'other']"/>
<!--
Remove tied elements which use the new let-ring
type for single-ended ties.
-->
<xsl:template
match="tied[@type = 'let-ring']"/>
<!--
Remove tremolo elements which use the new unmeasured
type for unmeasured tremolos.
-->
<xsl:template
match="tremolo[@type = 'unmeasured']"/>
<!--
Remove notehead elements with new notehead values.
-->
<xsl:template
match="notehead[. = 'circled' or . = 'other']"/>
<!--
Remove handbell elements with new handbell values.
-->
<xsl:template
match="handbell[. = 'belltree']"/>
<!--
Remove new figured bass elements.
-->
<xsl:template
match="figure/footnote | figure/level"/>
<!--
Remove new element-specific attributes.
-->
<xsl:template
match="accidental-mark/@parentheses |
accidental-mark/@bracket | accidental-mark/@size |
lyric/@time-only | note/@print-leger |
tap/@hand"/>
<!--
Remove line-length attribute from articulation elements.
-->
<xsl:template
match="doit/@line-length | falloff/@line-length |
plop/@line-length | scoop/@line-length"/>
<!-- Remove smufl attributes. -->
<xsl:template
match="accidental/@smufl | accidental-mark/@smufl |
arrow/@smufl | elision/@smufl |
notehead/@smufl | stopped/@smufl |
tremolo/@smufl |
other-articulation/@smufl | other-notation/@smufl |
other-ornament/@smufl | other-technical/@smufl"/>
<!--
Do not copy text for caesura elements, or for breath-mark
elements with new values.
-->
<xsl:template
match="caesura | breath-mark[. = 'upbow' or . = 'salzedo']">
<xsl:copy><xsl:apply-templates
select="*|@*|comment()|processing-instruction()"
/></xsl:copy>
</xsl:template>
<!--
Convert grace-cue sizes to grace size. This is consistent
with our removal of the cue element from notes that
contain both grace and cue elements.
-->
<xsl:template
match="@size[. = 'grace-cue']">
<xsl:attribute name="size">grace</xsl:attribute>
</xsl:template>
<!-- Additions in attributes.mod -->
<!-- Remove new id attributes. -->
<xsl:template
match="key/@id | time/@id |
clef/@id | transpose/@id |
measure-style/@id"/>
<!--
Remove key-accidental elements with new accidental values.
-->
<xsl:template
match="key-accidental[. = 'double-sharp-down' or
. = 'double-sharp-up' or . = 'flat-flat-down' or
. = 'flat-flat-up' or . = 'arrow-down' or
. = 'arrow-up' or . = 'other']"/>
<xsl:template
match="key-accidental/@smufl"/>
<!-- Remove except-voice elements. -->
<xsl:template
match="except-voice"/>
<!-- Additions in barline.mod -->
<!-- Remove new id attributes. -->
<xsl:template
match="barline/@id"/>
<!-- Additions in common.mod -->
<!-- Replace the n, pf, and sfzp elements with other-dynamics -->
<xsl:template match="n">
<xsl:element name="other-dynamics">
<xsl:text>n</xsl:text>
</xsl:element>
</xsl:template>
<xsl:template match="pf">
<xsl:element name="other-dynamics">
<xsl:text>pf</xsl:text>
</xsl:element>
</xsl:template>
<xsl:template match="sfzp">
<xsl:element name="other-dynamics">
<xsl:text>sfzp</xsl:text>
</xsl:element>
</xsl:template>
<!-- Remove new id attributes. -->
<xsl:template
match="fermata/@id | segno/@id |
coda/@id | dynamics/@id"/>
<!--
Remove accidental-text elements with new accidental values.
-->
<xsl:template
match="accidental-text[. = 'double-sharp-down' or
. = 'double-sharp-up' or . = 'flat-flat-down' or
. = 'flat-flat-up' or . = 'arrow-down' or
. = 'arrow-up' or . = 'other']"/>
<!-- Remove smufl attributes. -->
<xsl:template
match="accidental-text/@smufl | other-dynamics/@smufl |
coda/@smufl | segno/@smufl"/>
<!--
Remove enclosure attributes that have values of pentagon,
hexagon, heptagon, octagon, nonagon, or decagon.
-->
<xsl:template
match="@enclosure[. = 'pentagon' or . = 'hexagon' or
. = 'heptagon' or . = 'octagon' or
. = 'nonagon' or . = 'decagon']"/>
<!--
Do not copy text for fermata elements with new values.
-->
<xsl:template
match="fermata[. = 'double-angled' or
. = 'double-square' or . = 'double-dot' or
. = 'half-curve' or . = 'curlew']">
<xsl:copy><xsl:apply-templates
select="*|@*|comment()|processing-instruction()"
/></xsl:copy>
</xsl:template>
<!-- Additions in direction.mod -->
<!-- Remove new id attributes. -->
<xsl:template
match="direction/@id | direction-type/@id |
rehearsal/@id | words/@id |
wedge/@id | dashes/@id |
bracket/@id | pedal/@id |
metronome/@id | octave-shift/@id |
harp-pedals/@id | damp/@id |
damp-all/@id | eyeglasses/@id |
string-mute/@id | scordatura/@id |
image/@id | principal-voice/@id |
accordion-registration/@id |
percussion/@id | other-direction/@id |
harmony/@id | frame/@id |
grouping/@id | print/@id |
sound/@id"/>
<!-- Remove smufl attributes. -->
<xsl:template
match="glass/@smufl | pitched/@smufl |
other-direction/@smufl |
other-percussion/@smufl"/>
<!--
For safety, remove entire direction that has a new
MusicXML 3.1 direction-type child.
-->
<xsl:template
match="direction[direction-type[staff-divide]]"/>
<xsl:template
match="direction[direction-type[symbol]]"/>
<!--
Convert sostenuto pedal types to start (damper) pedal
types. We do this instead of removing the entire element
so that we do not leave a dangling pedal element with a
stop type after the conversion.
-->
<xsl:template
match="pedal/@type[. = 'sostenuto']">
<xsl:attribute name="type">start</xsl:attribute>
</xsl:template>
<!--
Remove pedal elements that have a number greater
than 1, then remove the number and abbreviated
attributes altogether. Make sure the tests have
the right priority so the directions are removed
first, before the number attribute is removed.
-->
<xsl:template
match="pedal/@number | pedal/@abbreviated"/>
<xsl:template priority="1"
match="direction[direction-type[pedal[@number != '1']]]"/>
<!-- Remove new optional elements. -->
<xsl:template
match="beat-unit-tied | metronome-arrows |
metronome-tied"/>
<!--
For safety, remove entire direction that has a new
enumeration value in percussion child elements.
-->
<xsl:template
match="direction[direction-type[percussion[beater[
. = 'drum stick' or . = 'slide brush on gong' or
. = 'superball']]]]"/>
<xsl:template
match="direction[direction-type[percussion[effect[
. = 'lotus flute' or . = 'megaphone']]]]"/>
<xsl:template
match="direction[direction-type[percussion[glass[
. = 'glass harmonica' or . = 'glass harp']]]]"/>
<xsl:template
match="direction[direction-type[percussion[membrane[
. = 'Chinese tomtom' or . = 'cuica' or
. = 'Indo-American tomtom' or . = 'Japanese tomtom' or
. = 'tabla']]]]"/>
<xsl:template
match="direction[direction-type[percussion[metal[
. = 'agogo' or . = 'bell tree' or
. = 'cencerro' or . = 'chain rattle' or
. = 'jaw harp' or . = 'jingle bells' or
. = 'musical saw' or . = 'shell bells' or
. = 'tam tam with beater']]]]"/>
<xsl:template
match="direction[direction-type[percussion[pitched[
. = 'celesta' or . = 'lithophone' or
. = 'steel drums' or . = 'tubaphone']]]]"/>
<xsl:template
match="direction[direction-type[percussion[stick[stick-type[
. = 'glockenspiel' or . = 'gum' or
. = 'hammer' or . = 'superball' or
. = 'wound']]]]]"/>
<xsl:template
match="direction[direction-type[percussion[wood[
. = 'bamboo scraper' or . = 'castanets with handle' or
. = 'football rattle' or . = 'quijada' or
. = 'rainstick' or . = 'reco-reco' or
. = 'whip']]]]"/>
<!-- Remove stick attributes. -->
<xsl:template
match="stick/@parentheses | stick/@dashed-circle"/>
<!-- Remove new image attributes. -->
<xsl:template
match="image/@height | image/@width"/>
<!-- Additions in layout.mod -->
<!-- Remove glyph elements. -->
<xsl:template
match="glyph"/>
<!--
Remove note-size element with a grace-cue type.
-->
<xsl:template
match="note-size[@type = 'grace-cue']"/>
<!-- Additions in score.mod -->
<!-- Remove credit-symbol elements. -->
<xsl:template
match="credit-symbol"/>
<!-- Remove new id attributes. -->
<xsl:template
match="credit/@id | credit-image/@id |
credit-words/@id | measure/@id"/>
<!-- Remove new image attributes. -->
<xsl:template
match="credit-image/@height | credit-image/@width"/>
<!-- Remove new measure attributes. -->
<xsl:template
match="measure/@text"/>
<!--
Convert score version attribute to 3.0.
-->
<xsl:template
match="score-partwise/@version">
<xsl:attribute name="version">3.0</xsl:attribute>
</xsl:template>
<!--
The identity transformation. Used for everything that
stays the same in 3.0.
-->
<xsl:template match="text()">
<xsl:value-of select="." />
</xsl:template>
<!--
Whitespace within an xsl:copy could cause problems with
empty elements.
-->
<xsl:template match="*|@*|comment()|processing-instruction()">
<xsl:copy><xsl:apply-templates
select="*|@*|comment()|processing-instruction()|text()"
/></xsl:copy>
</xsl:template>
</xsl:stylesheet>