There exists a wide range of means to extend XML Schemas. As railML® is intended for collaboration with other parties, there is a frame of rules to be considered on when and how to extend the railML® schema. If your extension does not fit into this frame this may bar the certification of your tool.
Considering #when to extend the schema follows very similar lines throughout all railML® versions.
When to extend the schema and what to respect before starting?
If you intend to define a new element, attribute or enumeration value or redefine an existing one, please, research carefully, whether a solution to your data exchange problem already exists. As data interoperability is the core aim of railML®, analogous data content within analogous use cases shall be exchanged in the same element and attribute. Therefore we have to avoid duplications, as they tend to make data incomprehensive and cause avoidable efforts. Interfaces with such duplicates will not be certified and will therefore generally be excluded from data exchange. To avoid this please respect the following rules in ascending order:
- Read this wiki and examine the schema carefully whether there exists a solution already. If you're not sure please contact the responsible scheme coordinator (link to the railML® website).
- Publish your intention in the railML-Forum (link to the railML® website). This has two advantages for you:
- If the element already exists, the redundancy will very likely get apparent before you have taken too much effort.
- The community can support you. Maybe others have the same demand and a new railML element or attribute can be added to the scheme.
- Before starting, inform the responsible scheme coordinator (link to the railML® website), as to provide a solution that fits into the context.
Please, also take notice of our guideline for participating in the development process.
How to extend the schema
In railML® 2 plus railML® 3.1, the proposed means of extending railML® to your needs were the <xs:any>-element for defining new elements, the <xs:anyAttribute>-element for defining new attributes and the generic type tOtherEnumerationValue for defining new enumeration values in designated places. Please, read Dev:UsingAny for an introduction.
In railML® 3.2 and higher, the required solution is to employ the xsi:type attribute to introduce extensions to the released railML® core. As instances of <xs:any> are likely to disrupt the validation process, all occurances have been removed at the switch from railML® 3.1 and railML® 3.2. Extensions via xs:anyAttribute and tOtherEnumerationValue are still viable, where existing. Please, read Dev:Using xsi:type for an introduction.
|Documentation on how to extend
In any case to extend your railML files you need to define a new namespace. “Namespace” is to be understood virtually here - there does not need to be a real XSD file with the definition. However, it is common to publish the namespace definition using an XSD file. In the sense of data exchange it is best practice - at least.
Your namespace needs an abbreviation and an identifier. In the example
my is the abbreviation and
https://www.my-company.com/my-department/ is the identifier. The abbreviation must be unique within the railML file. The identifier shall be unique throughout the world… To secure this, often URLs are used as identifiers - as in the example.
The usage of URLs as an identifier is very common and seems to imply to refer to a location on the internet. However this is not the original intention - an identifier is not a location! If you follow the identifiers starting with “http…”, in most cases you will find nothing…
To give your namespace a location (of the corresponding XSD file, if there is one), you have to use the attribute
xsi:schemaLocation. This attribute contains a space-separated list of namespaces and their locations; the locations being ‘real’ paths either into the Internet (URLs) or into the local file system. (See also Defining namespaces and validating railML files). The namespace location is optional but highly recommended as stated above.
Namespace identifier and abbreviation must be declared with the xmlns:… attribute before being used. The declaration is typically set into the root element (<railml>) but may also be set in any sub-element before the first occurrence of any member of the namespace.
If you do not want to use an URL (Uniform Ressource Locator (external link)) as an identifier - since there is no real location - you can use any other Uniform Ressource Identifier (URI) (external link) instead. To show that your identifier is virtual throughout, you should let it start with “urn:” instead of “http:” (urn is for Uniform Ressource Name) as:
You do not need to use as many levels as shown here but always remember that URIs shall be unique throughout the world. If your company’s abbreviation is likely to be not unique (as with all two- or three-letter-abbreviations: Use the whole name or include the country or the legal form. So,
urn:dbnetzag:railml_extensions:1.0 are much better than, say,
- Select an abbreviation for your namespace. Your software’s abbreviation will fit most likely.
- Select an identifier (URI) for your namespace. Typically, you can use the start of your URL to secure uniqueness or “something long starting with urn:”.
- Decide whether you can publish an XSD file with your namespace definition. If so, use the attribute xsi:schemaLocation to provide the location of your XSD file. This always shall be a real URL (Internet). If you do not want to publish the XSD, skip the xsi:schemaLocation for your namespace. Do not provide a “wrong” (virtual) location!