Skip to content

feat: expose musicxml id attributes in mx::api - #401

Open
webern wants to merge 1 commit into
mainfrom
claude/musicxml-id-attributes-api-rfi9qv
Open

feat: expose musicxml id attributes in mx::api#401
webern wants to merge 1 commit into
mainfrom
claude/musicxml-id-attributes-api-rfi9qv

Conversation

@webern

@webern webern commented Aug 18, 2026

Copy link
Copy Markdown
Owner

Human Summary

Model ID for those cases where the mx::api data model is close enough the MusicXML data model to make that simple.

Caveats:

  • ID strings are silently coerced into valid NCNames.
  • ID uniqueness is not yet enforced.

Summary

Starting with MusicXML 3.1 most elements can carry an id attribute naming that one element within the document. mx::api dropped nearly all of them (only a handful of recently-added direction types had one). This adds an optional id member to every api type that maps one-to-one onto an element with an id, and reads and writes it in mx::impl.

Types that gained an id:

Where MusicXML element
NoteData, LyricData note, lyric
MeasureData, BarlineData measure, barline
ClefData, KeyData, TimeChoice, TransposeData clef, key, time, transpose
DirectionData, SoundData direction, sound
WordsData, SymbolData, RehearsalData words, symbol, rehearsal
WedgeStart, WedgeStop wedge
SpannerStart, SpannerStop bracket, dashes, octave-shift
PedalLineData pedal
CurveStart, CurveContinue, CurveStop, TieLetRing slur, tied
TupletStart, TupletStop tuplet
FiguredBassData figured-bass

Supporting changes:

  • New src/private/mx/impl/IdFunctions.h with the two helpers (getId, setId) the readers and writers call.
  • ApiCommon.h explains what ids are for, and that mx repairs a malformed id but does not check uniqueness (see ID uniqueness is not constrained by mx::core. #397).
  • A carried-forward (implicit) time signature no longer keeps the previous measure's id; only the measure that states the <time> element carries it.
  • SoundData::isSpecified now counts an id, so a <sound> that has nothing but an id is not dropped.

Left out, because placing the id would need a design decision:

  • Grouping elements mx::api does not model as their own type: direction-type, notations, articulations, ornaments, technical, beam.
  • Marks folded into MarkData: dynamics, fermata, accidental-mark. These would need new MarkDataChoice alternatives.
  • harmony and frame: one DirectionData holds several ChordData that serialize into a single <harmony>, so it is not clear which chord owns the id.
  • credit: both <credit> and <credit-words> have an id and PageTextData models the pair.
  • Elements mx::api does not model at all: print, measure-style, grouping, for-part, glissando, slide (see api: model note-attached paired spanners (glissando, slide, wavy-line) #389).

Testing

  • New src/private/mxtest/api/IdAttributeApiTest.cpp: 7 cases, 53 assertions, covering every new field through roundTrip, plus one case reading ids straight off source XML and one pinning the implicit-time-signature rule
  • make test-all green: core roundtrip (839 cases), core unit (44 cases), api/impl suite (6018 assertions in 542 cases), api roundtrip (366 pinned, 0 failed)
  • Discovery went from 366 to 368 passing files; synthetic/bracket.3.1.xml and synthetic/dashes.3.1.xml newly pass because of the bracket and dashes ids, and are pinned in roundtrip-baseline.txt. No file regressed.
  • make fmt-check passes

References

Beginning with MusicXML 3.1 most elements can carry an id attribute that names
that one element within the document. mx::api dropped nearly all of them. Add an
optional id member to every api type that maps one-to-one onto an element with
an id, and read and write it in mx::impl.

New id fields: NoteData, MeasureData, ClefData, KeyData, TimeChoice,
TransposeData, BarlineData, LyricData, DirectionData, WordsData, SymbolData,
RehearsalData, WedgeStart, WedgeStop, SpannerStart, SpannerStop, PedalLineData,
CurveStart, CurveContinue, CurveStop, TieLetRing, TupletStart, TupletStop,
SoundData and FiguredBassData.

A new IdFunctions.h holds the two impl helpers that read and write the
attribute. ApiCommon.h explains what ids are for and the uniqueness rule that mx
does not enforce.

Left out are the elements where placing the id needs a design decision: the
grouping elements mx::api does not model (direction-type, notations,
articulations, ornaments, technical, beam), the marks folded into MarkData
(dynamics, fermata, accidental-mark), harmony and frame (one DirectionData holds
several ChordData that serialize into a single harmony), credit (both credit and
credit-words carry an id and PageTextData models the pair), and the elements
mx::api does not model at all (print, measure-style, grouping, for-part,
glissando, slide).

synthetic/bracket.3.1.xml and synthetic/dashes.3.1.xml now survive the strict
api round trip and are pinned in roundtrip-baseline.txt.
@webern webern added feature new feature request non-breaking fixes or implementation that do not require breaking changes api Affects the mx::api layer ai Issues opened by, or through, a coding agent. labels Aug 18, 2026 — with Claude
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai Issues opened by, or through, a coding agent. api Affects the mx::api layer feature new feature request non-breaking fixes or implementation that do not require breaking changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant