From d6b982290e3dc37f90ce4f7bbbc2a6ab10c2f415 Mon Sep 17 00:00:00 2001 From: Mathias Vanden Auweele Date: Sat, 24 Oct 2026 08:11:35 +0000 Subject: [PATCH 1/2] fix(web): show where anonymous types are nested in "Used by" An anonymous type has no users of its own, so the diagram of a local element such as TAF's Contacts showed a lone box. The diagram now follows the declaring element up through the containing types to a named type or global element, also for anonymous holders of a named type's users. Fixes #9 --- web/src/graph.ts | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/web/src/graph.ts b/web/src/graph.ts index a487edc..293fe3a 100644 --- a/web/src/graph.ts +++ b/web/src/graph.ts @@ -228,8 +228,33 @@ export function buildNeighborhood(m: Model, o: NeighborhoodOptions): GraphSpec { } const holder = containingType(m, u.by); if (holder === undefined || holder === tid) continue; - if (addType(holder)) edge({ key: `a${holder}-${u.by}-${tid}`, from: `c${holder}`, to: `c${tid}`, kind: "comp", label: by.name ?? "", id: u.by }); + if (addType(holder)) { + edge({ key: `a${holder}-${u.by}-${tid}`, from: `c${holder}`, to: `c${tid}`, kind: "comp", label: by.name ?? "", id: u.by }); + nesting(holder); + } + } + nesting(tid); + } + }; + + // An anonymous type is used only where it is declared: show the chain of + // types it is nested in, up to a named type or a global element. + const nesting = (tid: Id) => { + const seen = new Set(); + for (let t = tid; !m.comp(t).name && !seen.has(t); ) { + seen.add(t); + const decl = m.comp(t).parent; + if (decl === undefined || m.comp(decl).kind !== "element") return; + const d = m.comp(decl); + if (d.parent === undefined) { + if (take(`x${decl}`, () => ({ key: `x${decl}`, id: decl, kind: "element", name: d.name ?? "", stereotype: d.element?.abstract ? "«element, abstract»" : "«element»", attrs: [], hiddenAttrs: 0 }))) edge({ key: `t${decl}-${t}`, from: `x${decl}`, to: `c${t}`, kind: "typed" }); + return; } + const holder = containingType(m, decl); + if (holder === undefined || !addType(holder)) return; + const row = m.contentRows(holder).find((r) => r.id === decl); + edge({ key: `a${holder}-${decl}-${t}`, from: `c${holder}`, to: `c${t}`, kind: "comp", label: d.name ?? "", mult: row ? mult(row.min, row.max) : undefined, id: decl }); + t = holder; } }; From 55c14c8316bda10fb3a22164eaa5651cd11168b5 Mon Sep 17 00:00:00 2001 From: Mathias Vanden Auweele Date: Sat, 24 Oct 2026 08:11:35 +0000 Subject: [PATCH 2/2] feat(pages): add the TAF TSI 4.0 and legacy RINF examples TAF TSI 4.0 comes from ERA's telematics TSI repository on GitLab (pinned commit), next to the existing 3.5.0 example. The legacy RINF XSD comes from the ERA website and is left out with a warning when it cannot be downloaded or indexed. Closes #8 --- .github/workflows/pages.yml | 2 +- README.md | 4 ++-- THIRD_PARTY_NOTICES.md | 4 ++-- scripts/build-examples.sh | 36 +++++++++++++++++++++++++++++++++--- 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index d1d2fb4..0d7c622 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -3,7 +3,7 @@ name: Pages # Publishes the viewer on GitHub Pages: # https://matdata-eu.github.io/schema-explorer/ # with an examples catalog of freely redistributable schemas only: NeTEx, -# ERA TAF/TAP TSI, OASIS UBL 2.4 and the W3C schema for schemas are fetched +# ERA TAF/TAP TSI, legacy RINF, OASIS UBL 2.4 and the W3C schema for schemas are fetched # from their publishers and pre-indexed here (see scripts/build-examples.sh). railML and other non-redistributable schemas are # never published. diff --git a/README.md b/README.md index 10627ec..f6d218b 100644 --- a/README.md +++ b/README.md @@ -184,8 +184,8 @@ to it (for the source view). Any static host works: Only publish schemas whose licence allows it. The website's examples are fetched from their publishers at build time and -keep their own terms: NeTEx (GPL-3.0, NeTEx-CEN); TAF TSI and TAP TSI B.10 -schemas, source: European Union Agency for Railways (reproduction authorised, +keep their own terms: NeTEx (GPL-3.0, NeTEx-CEN); TAF TSI, TAP TSI B.10 +and legacy RINF schemas, source: European Union Agency for Railways (reproduction authorised, source acknowledged); UBL 2.4, copyright © OASIS Open 2024 (OASIS IPR Policy); XMLSchema.xsd and xml.xsd, copyright © W3C (W3C Document License); OSDM, UIC (Apache-2.0); JSON Schema 2020-12 meta-schemas, copyright © 2022 diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index c45f518..db46e93 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -29,8 +29,8 @@ time (see `scripts/build-examples.sh`) and published with their own terms; they are not part of this repository or the binary: - **NeTEx**, from , GPL-3.0. -- **TAF TSI** (technical documents baseline 3.5.0) and **TAP TSI B.10** (1.4) - XML schemas. Source: European Union Agency for Railways, +- **TAF TSI** (4.0, and technical documents baseline 3.5.0), **TAP TSI + B.10** (1.4) and legacy **RINF** XML schemas. Source: European Union Agency for Railways, . "Reproduction is authorised, provided the source is acknowledged" ([ERA disclaimer and copyright notice](https://www.era.europa.eu/content/disclaimer-and-copyright-notice)). - **UBL 2.4**, Universal Business Language Version 2.4, OASIS Standard, diff --git a/scripts/build-examples.sh b/scripts/build-examples.sh index 4ff8c46..bfef644 100755 --- a/scripts/build-examples.sh +++ b/scripts/build-examples.sh @@ -6,8 +6,8 @@ # Only freely redistributable schema sets go here, each fetched from its # publisher at build time (pinned URLs, cached in $WORK/downloads): # - NeTEx (GPL-3.0), from its public repository -# - ERA TAF TSI and TAP TSI B.10 schemas (ERA: reproduction authorised, -# source acknowledged) +# - ERA TAF TSI (4.0 and 3.5.0), TAP TSI B.10 and legacy RINF schemas +# (ERA: reproduction authorised, source acknowledged) # - OASIS UBL 2.4 (OASIS IPR Policy) # - W3C XML Schema for schemas (W3C document licence) # - UIC OSDM, OpenAPI with JSON schemas (Apache-2.0), from its public repository @@ -58,8 +58,22 @@ cp "$WORK/NeTEx/LICENSE" "$OUT/LICENSE" entry netex "NeTEx" "Network Timetable Exchange, the CEN standard for public transport data (NeTEx_publication.xsd)" "$NETEX_REV" \ "CEN TC278 · NeTEx-CEN" "GPL-3.0" "https://github.com/NeTEx-CEN/NeTEx" "ct/netex:StopPlace_VersionStructure" -# ERA TAF TSI, technical documents baseline 3.5.0 (message catalogue XML schema). ERA="Source: European Union Agency for Railways (https://www.era.europa.eu). Reproduction is authorised, provided the source is acknowledged." + +# ERA TAF TSI 4.0 (message catalogue XML schema), from the ERA telematics TSI repository. +TAF4=https://gitlab.com/era-europa-eu/public/era-telematics-tsi/tsi_telematics/-/raw/2daa71cfb37b87ee16b5e85352a365fde9a3dc91/TD_105_xsd +if fetch $TAF4/taf_cat_complete.xsd taf-4.0-taf_cat_complete.xsd && + fetch $TAF4/taf_cat_codelists.xsd taf-4.0-taf_cat_codelists.xsd && + fetch $TAF4/TAP_TSI_codelist.xsd taf-4.0-TAP_TSI_codelist.xsd; then + start taf-tsi-4 + for f in taf_cat_complete taf_cat_codelists TAP_TSI_codelist; do cp "$DL/taf-4.0-$f.xsd" "$OUT/xsd/$f.xsd"; done + echo "$ERA" > "$OUT/NOTICE" + "$CLI" index "$OUT/xsd/taf_cat_complete.xsd" -o "$OUT/bundle.json" + entry taf-tsi-4 "TAF TSI 4.0" "Telematics Applications for Freight: the common message catalogue of the ERA technical documents, version 4.0 (taf_cat_complete.xsd)" "4.0.0" \ + "European Union Agency for Railways" "ERA, source acknowledged" "https://gitlab.com/era-europa-eu/public/era-telematics-tsi/tsi_telematics" +else echo "warning: TAF TSI 4.0 schemas not downloaded, example left out" >&2; fi + +# ERA TAF TSI, technical documents baseline 3.5.0 (message catalogue XML schema). TAF=https://www.era.europa.eu/system/files/2024-06 if fetch $TAF/taf_cat_complete.xsd taf-3.5.0-taf_cat_complete.xsd && fetch $TAF/taf_cat_codelists_0.xsd taf-3.5.0-taf_cat_codelists.xsd && @@ -82,6 +96,22 @@ if fetch https://www.era.europa.eu/system/files/2022-11/tap_tsi_b.10_1.4_1.xsd t "European Union Agency for Railways" "ERA, source acknowledged" "https://www.era.europa.eu/era-folder/tap-baseline-142-archive" else echo "warning: TAP TSI B.10 schema not downloaded, example left out" >&2; fi +# ERA RINF, the XML schema of the legacy Register of Infrastructure application +# (the data upload format used before the RINF knowledge graph). +if fetch "https://www.era.europa.eu/system/files?file=2022-11/rinf_schema_en.xsd" rinf-legacy.xsd && + grep -q 'schema' "$DL/rinf-legacy.xsd"; then + start rinf-legacy + cp "$DL/rinf-legacy.xsd" "$OUT/xsd/rinf_schema_en.xsd" + echo "$ERA" > "$OUT/NOTICE" + if "$CLI" index "$OUT/xsd/rinf_schema_en.xsd" -o "$OUT/bundle.json"; then + entry rinf-legacy "RINF (legacy)" "Register of Infrastructure: the XML schema of the legacy RINF application, used to upload infrastructure data to ERA (rinf_schema_en.xsd)" "2022" \ + "European Union Agency for Railways" "ERA, source acknowledged" "https://www.era.europa.eu/domains/registers/rinf_en" + else + echo "warning: legacy RINF schema could not be indexed, example left out" >&2 + rm -rf "$OUT" + fi +else echo "warning: legacy RINF schema not downloaded, example left out" >&2; fi + # OASIS UBL 2.4: every document schema of the release (xsd/maindoc) and the common modules. if fetch https://docs.oasis-open.org/ubl/os-UBL-2.4/UBL-2.4.zip UBL-2.4.zip; then start ubl