Rule files
XMAS-Core keeps both its XPlanung migration and its style rules as data, in two YAML files. Both files and a JSON Schema (draft 2020-12) for each are published, so other software can read the rules, implement them, or write rules of its own in the same format.
| Rule file | JSON Schema | |
|---|---|---|
| Migration | rules/migration/rules.yaml |
rules/migration/rules.schema.json |
| Style | rules/style/rules.yaml |
rules/style/rules.schema.json |
The rule files also ship in the package.
The schemas are generated from the models XMAS-Core loads the rules with, so they always describe what that release accepts.
Both schemas describe the files after YAML parsing, with anchors and aliases resolved.
The files are kept in a canonical form: sorted, with repeated parts aliased and notes in
comment: fields rather than YAML comments, which XMAS-Core refuses below the header. A
third-party file does not need to follow that form to be valid.
Migration rules
One entry of migrations: per version hop. A migration from 4.1 to 6.1 takes the hops
4.1 → 5.4 → 6.0 → 6.1, one after the other.
templates: # anything written more than once, anchored here and aliased where used
bm_drop: &bm_drop
op: drop
attrs: [BMZmin, BMZmax, BMmin, BMmax]
migrations:
- from: "4.1"
to: "5.4"
comment: a note on the hop as a whole
pre: [...] # collection operations, on the 4.1-shaped data, before the rules
rules:
BP_BaugebietsTeilFlaeche: # a feature or data type: a list of operations
- *bm_drop
BP_ErhaltungsGrund: # an enumeration: a code table
map:
"1000": "17000"
"2000": "17001"
unmapped: drop
post: [...] # collection operations, on the 5.4-shaped data, after the rules
Rules
rules: is keyed by class name in the from version.
- A feature type or data type takes a list of operations. They run in order on the feature's data, a plain mapping of attribute names to values, and nothing else: a rule cannot see another feature. A rule applies to the class and to every class derived from it, and a feature runs the rules of its whole inheritance chain, most abstract first. A rule on a data type reaches it wherever it is nested.
- An enumeration takes a code table:
map:from each old code to its new code, a list of codes, ornullfor a code with no successor;unmapped:says whether a code the table does not list is kept (keep, the default) or dropped (drop). It applies to every attribute of that enumeration.
Nothing in a rule states what the target schema already says, such as whether a value becomes a list. XMAS-Core reads that from the target appschema.
Operations
op |
Does |
|---|---|
retype |
Writes the feature out as another feature type (to:), or one per plan type (by_plan:). |
set |
Sets an attribute (attr:) to a fixed value:, another attribute's value (from:) or a value per plan type (by_plan:); if_unset: leaves a set value alone. |
drop |
Removes attributes (attrs:) the target does not have, reporting each value it drops. |
move |
Moves one or more attributes (from:) into another (to:); set: tags each moved value. |
map |
Rewrites one attribute's codes through a code table (map:, unmapped:), in place or into to:. |
fold |
Collects several attributes (attrs:, source → field) into the nested object(s) of to:. |
warn |
Reports something about the feature without changing it. |
remove |
Drops the whole feature; abort: true stops the migration. |
Every operation takes a comment:, a warn: code and a message: for what it reports, and:
when:— guards, one clause or a list of them that must all hold. A clause names one subject,attr:orattrs:, and at most one predicate: none (the attribute has a value),is:,in:,contains:orgeom:(a geometry type by its UML name).not: truenegates the predicate, andany: trueasks for only one ofattrs:.then:— operations that run only when this operation's guard holds, one level deep.
The warn: codes are the tokens of WarnCode.
Collection operations
pre: and post: hold the only operations that may look at more than one feature. Starting from
each feature of class each:, they follow the association roles in via::
pullcopies something from the features it reaches back onto the starting feature (from:/to:, orattrs:for attributes that keep their name).pushwrites onto the features it reaches: fixed values (set:), or the starting feature's id into a role (to:), which is how an inverse role gets filled in.
Their when: clauses test the features the roles reached, and may also test a class with
is_a:.
The full semantics of every field are in the reference for single-feature operations and collection operations.
Style rules
One entry per stylesheetId. Styling a presentational object (XP_PTO, XP_PPO, ...) picks the
rule whose selector matches the attributes its art references, sets its stylesheetId and,
for a text object, fills schriftinhalt from the rule's template.
6165535a-151f-447e-b080-31cd0e445271: # the stylesheetId
comment: Dachneigung # which Planzeichen the rule represents
versions:
"5.4": &6165535a-151f-447e-b080-31cd0e445271_5_4
text: D{DN} # template for schriftinhalt
selector:
DN: # an attribute art references
value: ["*"]
type: Angle
"6.0": *6165535a-151f-447e-b080-31cd0e445271_5_4
"6.1": *6165535a-151f-447e-b080-31cd0e445271_5_4
Rules
The key is a UUID. A matching object gets
https://registry.gdi-de.org/codelist/de.xleitstelle.xplanung/XP_StylesheetListe/<key> as its
stylesheetId. comment: is a note for the reader, and says which Planzeichen the rule stands
for.
versions: maps an XPlanung version ("5.4", "6.0", "6.1") to the rule as it applies there,
since attribute and type names differ between versions. A version whose rule equals an earlier
version's aliases it (*<key>_<version>) rather than repeating it. A version the rule does not
list is not styled by it.
Selector and text
| Field | Means |
|---|---|
selector |
Keyed by attribute name: art has to reference exactly these attributes, no more and no fewer. A rule without a selector matches nothing. |
selector.<attr>.type |
The attribute's type name in that version (BP_Dachform, Angle, ...). |
selector.<attr>.value |
The values it may hold, as codes or text, or ["*"] for any value. |
text |
Optional template for schriftinhalt, with the selected attributes as {placeholders}. |
In text, an enumeration is written as its short form (kuerzel or lesbarerName) rather than
its code, a measure with its unit, and a Z attribute (number of storeys) as a Roman numeral.