miqwit / dedex
Parse DDEX ERN files and provide a convenient API to use it
Requires (Dev)
- goetas-webservices/xsd2php: ^0.4.4
- goetas-webservices/xsd2php-runtime: v0.2.16
- phpunit/phpunit: ^10.5
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-master
- 2.6.0
- 2.5.0
- 2.4.1
- 2.4.0
- 2.3.1
- v2.3.0
- 2.2.0
- 2.1.1
- 2.1.0
- 2.0.7
- 2.0.6
- 2.0.5
- 2.0.4
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0.0
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
- dev-feature/rule-violations
- dev-fix/rules-ern4x
- dev-feature/ern-381-support
- dev-version-431
- dev-bug/ern382-bug-track-release
- dev-chore/xml-free-parser-warning
- dev-bug/ern411-simplifier-deal
- dev-add-ci-workflow
- dev-phpunit-vulnerability
- dev-support-ern-42
- dev-support-more-versions
- dev-StandaloneLibrary
- dev-bugfix/purged-release
- dev-bugfix/no-deals-in-simple-album
- dev-add-simple-functions
- dev-bugfix/errors-as-exceptions
- dev-php8
- dev-bugfixes
- dev-ddex411
- dev-fix-instanciation-with-objects
This package is auto-updated.
Last update: 2026-10-25 08:06:17 UTC
README
ℹ️ 🇨🇦 I will be at the 16-19 November Toronto, Canada 46th Plenary Meeting. Meet me there!
DeDEX is a DDEX XML file parser. DDEX is a standard used in the music industry to deliver rich media content. See more info at ddex.net. This covers only the ERN (Electronic Release Notification) standard, for the following versions.
Supported versions:
3.8.13.8.24.14.1.14.24.34.3.14.3.2
Simple Entities speak your language and will make you smoothly parse your first ERNs.
Rule (and Rules Set) contain the minimal consistent information YOU need in your system. XML may be valid, but inaccurate for your needs.
I created this DDEX ERN parser that is as convenient as I always hoped for.
✍️ Contribute here if you feel like it. Make DeDEX the first repo you contribute to! 🙌
⭐️ If you find this work useful, please star the repository.
Installation
composer require miqwit/dedex
⚠️ Runtime: PHP 7.4+. As per composer configuration, development and test tools need 8.1+ to work. It is not maintained for 7.4+ versions.
Usage
Convert a DDEX file to a SimpleAlbum
use DedexBundle\Controller\ErnParserController; use DedexBundle\Simplifiers\SimpleAlbum; $xml_path = "tests/Ern382/samples/with_assets/complete_flac/1199119911991.xml"; $parser = new ErnParserController(); $ern = $parser->parse($xml_path); $album = new SimpleAlbum($ern); // Then you can access high level property of this album $release_date = $album->getOriginalReleaseDate(); $artists_at_album_level = $album->getArtists(); $tracks_for_cd_1 = $album->getTracksPerCd()[1]; // You can also access exact XML mapping by getting // ddex objects at album or track level $ddex_release = $album->getDdexRelease(); $ddex_release->getReleaseId()[0]->getICPN()->value(); // direct access $ddex_track = $tracks_for_cd_1[1]->getDdexSoundRecording()->getDuration(); // direct access
Parse a file without XSD validation
use DedexBundle\Controller\ErnParserController; $xml_path = "tests/Ern382/samples/audioalbum_complete.xml"; $parser = new ErnParserController(); $ern = $parser->parse($xml_path); // Then you can access properties of the ERN $created_at = $ern->getMessageHeader()->getMessageCreatedDateTime();
Parse a file with XSD validation
XSD validation will load all XML and XSD in memory, making this library less efficient. Use with care. Is not adapted to gigantic files.
use DedexBundle\Controller\ErnParserController; $xml_path = "tests/Ern382/samples/audioalbum_complete.xml"; $parser = new ErnParserController(); $parser->setXsdValidation(true); $ern = $parser->parse($xml_path);
Parse a file with Rules
use DedexBundle\Controller\ErnParserController; use DedexBundle\Rule\AtLeastOneImage; use DedexBundle\Exception\RuleValidationException; $xml_path = "tests/Ern382/samples/audioalbum_complete.xml"; $parser = new ErnParserController(); $parser->addRule(new AtLeastOneImage(Rule::LEVEL_ERROR)); // ... can add multiple rules one by one // ... or multiple rules with $parser->addRuleSet([]) $ern = $parser->parse($xml_path); // will raise an RuleValidationException if rule is broken
Read rule results
Each rule gives a result (passed, failed or skipped), and a failed rule gives one Violation per problem: what failed, about which element (getSubject(), like A9), and where it is in the XML (getPath()).
use DedexBundle\Controller\ErnParserController; use DedexBundle\Rule\RuleSet; $parser = new ErnParserController(); $parser->setThrowOnRuleError(false); // parse() returns the message even if an ERROR rule fails $parser->addRuleSet(RuleSet::MUSICAL_ALBUM("path/to/assets")); $ern = $parser->parse($xml_path); foreach ($parser->getRuleResults() as $result) { echo $result->getRule()->getName(), ": ", $result->getStatus(), "\n"; // passed, failed or skipped foreach ($result->getViolations() as $violation) { echo " ", $violation, "\n"; // WARNING: Resource A9 is not used in any release echo " ", $violation->getSubject(), "\n"; // A9 echo " ", $violation->getPath(), "\n"; // ResourceList/Image[2] } }
A path is relative to the root element of the message, with element local names separated by / and an optional 1-based position among same-named siblings, like ResourceList/SoundRecording[3]/SoundRecordingEdition/ResourceId. The equivalent XPath is /* followed by /*[local-name()='Segment'][n] for each segment.
Rules can also run on a message that is already parsed: RuleRunner::run($rules, $ern, $version).
Write a rule
Extend Rule, call fail() for each problem, and return whether the message passes:
use DedexBundle\Rule\Rule; class AllSoundRecordingsHaveDuration extends Rule { protected $message = "All SoundRecordings must have a duration."; public function validates($newReleaseMessage): bool { $this->resetMessage(); foreach (array_values($newReleaseMessage->getResourceList()->getSoundRecording()) as $i => $sr) { if ($sr->getDuration() === null) { $ref = $sr->getResourceReference(); $this->fail("SoundRecording $ref has no duration", $ref, sprintf("ResourceList/SoundRecording[%d]", $i + 1)); } } return count($this->getViolations()) === 0; } }
A rule that only returns false (without calling fail()) still works: its message becomes its single violation.
Parser config
Here are handy function from the parser.
$parser=new ErnParserController();
$parser->setDisplayLog(true);
Displays parsing logs. For debugging purpose mainly. (default: false)
$parser->setXsdValidation(true);
Validates XML against XSD. (default: false because will load XSD and XML in memory)
$parser->getRuleMessages();
Returns a formatted string (with new lines) of all the errors generated by the rule checking. To be called when parsing ended.
If one of the ERROR rules fail, the parser will throw an exception with these messages.
$parser->getRuleResults();
Returns one RuleResult per rule, in the order they were added, with its status and its violations (see Read rule results). Available after parsing, even when parse() threw.
$parser->setThrowOnRuleError(false);
With false, parse() does not throw when an ERROR rule fails: read the failures with getRuleResults() or getRuleMessages(). (default: true)
$parser->addRuleSet();
Will store a set of Rule (array). For example, each provider could be check with a specific rule set.
Standard updates
Official email in September 2024
From March 1, 2025, all the versions 3 as well as version 4.0 of the Electronic Release Notification standard, their respective profiles, and choreographies will no longer be supported. This means that from that date, no further updates, bug fixes, or AVS additions will be made to these versions of the ERN standard. Also, the XML schemas and all articles or implementation advice about ERN- 3 and ERN 4.0 will be removed from all DDEX websites. All schemas, standard texts, and supporting information about ERN -4.1, 4.2, and, of course, 4.3.1 will remain.