Specification: Codelist Aliases in Hierarchy XLSX
1. Purpose
This concept originated in the SDMX 2.1 HierarchicalCodelistBean, where getCodelistAlias(String codelistURN) maps a codelist URN to a short alias string. The XLSX writer adapts this pattern for the HierarchyBean.
2. Format Requirements
Aliases must conform to the SDMX IDType format, which is defined as the regular expression:
[A-Za-z0-9_@$-]+
This means:
- One or more characters from: ASCII letters (upper or lower case), digits, underscore (_), at-sign (@), dollar sign ($), hyphen (-)
- No whitespace, no dots, no slashes, no colons, no other punctuation
In practice, aliases will typically be simple alphanumeric strings (e.g. CL_ACTIVITY, CL_REF, CODELIST_1).
Note: An alias does not need to match the identifier of the corresponding codelist. Any
IDType-conformant string is acceptable. The recommendations in Section 3 are conventions for this codebase's writer, not enforced constraints.
3. Default Alias Generation Convention (This Codebase)
When the hierarchy XLSX writer automatically assigns aliases during output generation, it follows this convention:
3.1 Normal Case — Unique Identifiers
For each codelist referenced in the hierarchy, the alias is set to the codelist's identifier (i.e. the getMaintainableId() value from the code reference, without agency, version, or any other URN component).
Example:
| Codelist URN | Alias |
|---|---|
urn:sdmx:org.sdmx.infomodel.codelist.Code=EXAMPLE:CL_ACTIVITY(1.0) |
CL_ACTIVITY |
urn:sdmx:org.sdmx.infomodel.codelist.Code=OTHER:CL_AREA(2.0) |
CL_AREA |
3.2 Collision Case — Same Identifier, Different URNs
When two or more codelists share the same identifier but have different URNs (different agency, version, or both), using the bare identifier would violate the uniqueness requirement. In this case the writer appends a numeric suffix _1, _2, _3, … to the identifier, assigning suffixes in the order the codelists are encountered during iteration.
Example:
| Codelist URN | Alias |
|---|---|
urn:sdmx:org.sdmx.infomodel.codelist.Code=AGENCY_A:CL_REF(1.0) |
CL_REF_1 |
urn:sdmx:org.sdmx.infomodel.codelist.Code=AGENCY_B:CL_REF(1.0) |
CL_REF_2 |
urn:sdmx:org.sdmx.infomodel.codelist.Code=AGENCY_A:CL_REF(2.0) |
CL_REF_3 |
Clarification on ordering: The suffix reflects iteration order, not any semantic ranking. The same codelists processed in a different order could receive different suffix numbers. The only guarantee is that all assigned aliases are unique within the spreadsheet.
3.3 This Convention Is Codebase-Local
The _1/_2/_3 collision-resolution strategy is a convention specific to this writer implementation. It is not part of the SDMX standard and is not mandated by any cross-format rule. An alternative implementation — in another codebase, or even in a different writer within this project — may legitimately use a different strategy, including but not limited to:
- Including the agency prefix in the alias (e.g.
AGENCY_A_CL_REF) - Appending a shortened version hash
- Generating random unique strings (e.g. UUIDs)
Any strategy that satisfies Section 2 (format) and the uniqueness requirement (see format_design_spec.md §4.3) is conformant.
4. Test Cases
4.1 Single Codelist — Alias Equals Identifier
Scenario: A hierarchy references exactly one codelist.
Input: One codelist with id CL_SIMPLE, agency EXAMPLE, version 1.0.
Expected: The alias assigned is CL_SIMPLE.
4.2 Multiple Codelists — No Collision
Scenario: A hierarchy references two codelists whose identifiers are distinct.
Input:
- EXAMPLE:CL_ACTIVITY(1.0)
- EXAMPLE:CL_AREA(1.0)
Expected aliases:
- CL_ACTIVITY → CL_ACTIVITY
- CL_AREA → CL_AREA
No suffix is appended. No collision occurs.
4.3 Two Codelists — Identifier Collision (Different Agency)
Scenario: Two codelists have the same identifier but different agencies.
Input:
- AGENCY_A:CL_REF(1.0)
- AGENCY_B:CL_REF(1.0)
Expected aliases:
- AGENCY_A:CL_REF(1.0) → CL_REF_1
- AGENCY_B:CL_REF(1.0) → CL_REF_2
Both aliases are unique. Neither is simply CL_REF.
4.4 Two Codelists — Identifier Collision (Different Version)
Scenario: Two codelists have the same identifier and agency but different versions.
Input:
- EXAMPLE:CL_REF(1.0)
- EXAMPLE:CL_REF(2.0)
Expected aliases:
- EXAMPLE:CL_REF(1.0) → CL_REF_1
- EXAMPLE:CL_REF(2.0) → CL_REF_2
4.5 Three Codelists — Identifier Collision (Three-Way)
Scenario: Three codelists share the same identifier.
Input:
- AGENCY_A:CL_REF(1.0)
- AGENCY_B:CL_REF(1.0)
- AGENCY_A:CL_REF(2.0)
Expected aliases:
- AGENCY_A:CL_REF(1.0) → CL_REF_1
- AGENCY_B:CL_REF(1.0) → CL_REF_2
- AGENCY_A:CL_REF(2.0) → CL_REF_3
Suffixes are _1, _2, _3 in iteration order.
4.6 Mixed Case — Some Collisions, Some Not
Scenario: A hierarchy references four codelists: two share an identifier, two have unique identifiers.
Input:
- EXAMPLE:CL_ACTIVITY(1.0) (unique identifier)
- AGENCY_A:CL_REF(1.0) (collides with next)
- AGENCY_B:CL_REF(1.0) (collides with previous)
- EXAMPLE:CL_AREA(1.0) (unique identifier)
Expected aliases:
- CL_ACTIVITY(1.0) → CL_ACTIVITY
- AGENCY_A:CL_REF(1.0) → CL_REF_1
- AGENCY_B:CL_REF(1.0) → CL_REF_2
- CL_AREA(1.0) → CL_AREA
Unique-identifier codelists keep their plain identifier. Colliding codelists receive suffixes. All aliases in the spreadsheet remain distinct.