feat: dynamic field labels, optionally overriding field names per species

This commit is contained in:
Lewis Wynne 2026-04-07 18:17:41 +01:00
parent a0060ca4bb
commit a2b904811a
21 changed files with 322 additions and 73 deletions

View file

@ -5,7 +5,7 @@ import type { Template, RecordDef, FieldDef, SelectOption } from '../types';
const parser = new XMLParser({
ignoreAttributes: false,
attributeNamePrefix: '@_',
isArray: (name) => ['entry', 'ref', 'field', 'record', 'option', 'citizenship', 'language'].includes(name),
isArray: (name) => ['entry', 'ref', 'field', 'record', 'option', 'citizenship', 'language', 'label'].includes(name),
trimValues: true
});
@ -14,6 +14,15 @@ function extractRefs(container: any): string[] {
return container.ref.map((r: any) => r['@_id']);
}
function extractLabels(container: any): Record<string, string> {
if (!container?.label) return {};
const labels: Record<string, string> = {};
for (const l of container.label) {
labels[l['@_for']] = typeof l === 'string' ? l : l['#text'];
}
return labels;
}
export function parseSpecies(xml: string): SpeciesData {
const root = parser.parse(xml).species;
const subspecies = root.subspecies?.entry ?? [];
@ -22,7 +31,7 @@ export function parseSpecies(xml: string): SpeciesData {
id: root['@_id'],
name: root['@_name'],
description: root.description?.trim(),
subspeciesLabel: root['@_subspeciesLabel'],
labels: extractLabels(root.labels),
languages: extractRefs(root.languages),
citizenships: extractRefs(root.citizenships),
subspecies: subspecies.map((e: any) => ({