Dev:UsingAny
There are multiple possibilities for extending the officially published railML schemas by own needs, e.g. elements, attributes and enumeration values. The following sections show how to achieve this in a valid form.
Important: Before starting using :any
please read carefully and understand the section below!
New elements, respective sub-trees (Use of xs:any)
There are multiple positions where the railML schemas provide the W3C xs:any element for optional extension by own elements, respective sub-trees. That's the case for all elements with the generic railML attributes id, code, name, description... and at other certain positions in the XML tree forseen for extensibility.
<xs:any namespace="##other" processContents="strict" minOccurs="0" maxOccurs="unbounded" />
- namespace="##other" means that the railML schemas force the extensions to be defined in an own new namespace that differs from the railML one. See also Namespace handling
- processContents="strict" means that the railML schemas force all extensions to be defined by an XML Schema (*.xsd).
- minOccurs="0" means that there may be no extensions at this certain position.
- maxOccurs="unbounded" means that the railML schemas allow an "unbounded" amount of extension elements at this certain position.
In case of general extensions this feedback should be provided to the railML community e.g. by announcing in the appropriate railML forum or at minimum by mail to the appropriate railML coordinator.
Example for an extension XML Schema defining new elements without any railML re-use
XML Schema with comments
<?xml version="1.0" encoding="UTF-8"?> <xs:schema targetNamespace="http://www.my-company.com/my-department/" xmlns="http://www.my-company.com/my-department/" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0"> <!-- Person to contact in case of any questions regarding the schema: Max Mustermann, phone: +12-345-67890, mail: max.mustermann@my-company.com --> <xs:element name="mySpecifics"> <xs:annotation> <xs:documentation>Our companies' extensions follow in this sub-tree</xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element name="contract" type="contractType" minOccurs="0"> <xs:annotation> <xs:documentation>Each element may be enriched with contract details.</xs:documentation> </xs:annotation> </xs:element> <xs:element name="personResponsible" type="xs:string"> <xs:annotation> <xs:documentation>Each element should be defined with a person that is responsible for the content.</xs:documentation> </xs:annotation> </xs:element> </xs:sequence> <xs:attribute name="version" type="xs:string" use="required"/> </xs:complexType> </xs:element> <xs:complexType name="contractType"> <xs:sequence> <xs:element name="number" type="xs:string"> <xs:annotation> <xs:documentation>In case the contract details are known, the contract number for this element should be defined.</xs:documentation> </xs:annotation> </xs:element> <xs:element name="requirement" type="xs:string" maxOccurs="unbounded"> <xs:annotation> <xs:documentation>In case the contract details are known, the requirements numbers for this element should be defined.</xs:documentation> </xs:annotation> </xs:element> </xs:sequence> </xs:complexType> </xs:schema>
- This example does not re-use railML elements, attributes, attribute groups, types, groups. It is fully based on XML Schema types. (lines 17, 23, 29, 34)
- The version attribute in the root element marks the version of the extension schema and should be not confused with the railML version. (line 2)
- It is recommended to use the XML comments for non-content related documentation, e.g. contact information: <!-- ... --> (line 4)
- It is recommended to use the XML Schema possibilities for documentation inside the extension schema: xs:annotation and xs:documentation (lines 7-9, 13-15, 18-20, 30-32, 35-37)
- The elements mySpecifics and contract show how to define sub-trees: xs:complexType (lines 10-24, 27-40)
- The elements personResponsible, number and requirement however define single elements without children. (lines 17, 29, 34)
- The element contract may occur once or not at all at the certain position. (line 12)
- The element personResponsible must occur ones. (line 17)
- In case the element contract is used the elements number and requirement have to be used, too. The element requirement may occur more than once. (lines 29, 34)
- The attribute version has to be defined inside the element mySpecifics. (line 23)
The following XML instance document shows an example how to deploy these extensions within a railML file.
XML Instance with comments
<?xml version="1.0" encoding="UTF-8"?> <railml xmlns="http://www.railml.org/schemas/2011" xmlns:my="http://www.my-company.com/my-department/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.railml.org/schemas/2011 ../schema/railML.xsd http://www.my-company.com/my-department/ usingAnyElement.xsd" version="2.1"> <timetable id="tt1"> <my:mySpecifics version="1.0"> <my:contract> <my:number>1234-56/789</my:number> <my:requirement>123.456.78.9</my:requirement> </my:contract> <my:personResponsible>Max Mustermann</my:personResponsible> </my:mySpecifics> <categories> <category id="c1" code="IC" name="InterCity" description="Fast large city connection" trainUsage="passenger"> <my:mySpecifics version="1.0"> <my:personResponsible>Marie Mustermann</my:personResponsible> </my:mySpecifics> </category> <category id="c2" code="RE" name="RegionalExpress" description="Fast small city connection" trainUsage="passenger"/> </categories> </timetable> </railml>
- The element timetable shows the full usage of the extension elements and attributes. (lines 4-10)
- The first category element shows the usage of all required extension elements and attributes. (lines 13-15)
- The second category element shows the absence of the extension elements and attributes. (line 17)
- The extensions are clearly distinguishable from the railML core by defining the appropriate namespace: xmlns:my="http://www.my-company.com/my-department/" (line 2), using the prefix my (lines 4-10, 13-15)
Generally, the prefix is a short abbreviation for the domain-specific extension up to three letters.
Extensions in railML base elements (with id, code...) have to be inserted before the other railML child elements. In all other cases do the extensions apply after the railML child elements.
Example for an extension XML Schema defining new elements with some railML re-use
XML Schema with comments
<?xml version="1.0" encoding="UTF-8"?> <xs:schema targetNamespace="http://www.my-company.com/my-department/" xmlns="http://www.my-company.com/my-department/" xmlns:rail="http://www.railml.org/schemas/2011" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0"> <!-- Person to contact in case of any questions regarding the schema: Max Mustermann, phone: +12-345-67890, mail: max.mustermann@my-company.com --> <xs:import namespace="http://www.railml.org/schemas/2011" schemaLocation="../schema/railML.xsd"> <xs:annotation> <xs:documentation>Copyright (c) railML.org; All Rights Reserved.</xs:documentation> <xs:documentation>This work is licensed under a Creative Commons Attribution 2.0 License. http://creativecommons.org/licenses/by/2.0/</xs:documentation> <xs:documentation>For further information see: http://www.railml.org/</xs:documentation> </xs:annotation> </xs:import> <xs:element name="mySpecifics"> <xs:annotation> <xs:documentation>Our companies' extensions follow in this sub-tree</xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element name="contract" type="contractType" minOccurs="0"> <xs:annotation> <xs:documentation>Each element may be enriched with contract details.</xs:documentation> </xs:annotation> </xs:element> <xs:element name="personResponsible" type="xs:string"> <xs:annotation> <xs:documentation>Each element should be defined with a person that is responsible for the content.</xs:documentation> </xs:annotation> </xs:element> </xs:sequence> <xs:attribute name="version" type="rail:tVersionNumber" use="required"/> </xs:complexType> </xs:element> <xs:complexType name="contractType"> <xs:complexContent> <xs:extension base="rail:tElementWithIDAndNameWithoutAny"> <xs:annotation> <xs:documentation>In case the contract details are known, the contract number for this element should be defined within the 'code' attribute.</xs:documentation> </xs:annotation> <xs:sequence> <xs:element name="requirement" type="rail:tGenericName" maxOccurs="unbounded"> <xs:annotation> <xs:documentation>In case the contract details are known, the requirements numbers for this element should be defined.</xs:documentation> </xs:annotation> </xs:element> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> </xs:schema>
- The railML namespace has to be declared in any case where elements, attributes, types or groups are reused in the extension: xmlns:rail="http://www.railml.org/schemas/2011" (line 2)
- The railML namespace has further to be imported using the XML Schema rules: xs:import. (lines 6-12)
- The element requirement re-uses the railML type tGenericName. (line 42)
- The attribute version re-uses the railML type tVersionNumber. (line 31)
- The content of element contract re-uses the railML base type tElementWithIDAndNameWithoutAny thats provides some generic attributes and elements. (lines 37-48)
- This example has many in common with the previous one. See that comments, too.
The following XML instance document shows an example how to deploy these extensions within a railML file.
XML Instance with comments
<?xml version="1.0" encoding="UTF-8"?> <railml xmlns="http://www.railml.org/schemas/2011" xmlns:my="http://www.my-company.com/my-department/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.railml.org/schemas/2011 ../schema/railML.xsd http://www.my-company.com/my-department/ usingAnyElementWithRailML.xsd" version="2.1"> <timetable id="tt1"> <my:mySpecifics version="1.0"> <my:contract id="ctr1" code="1234-56/789"> <my:requirement>123.456.78.9</my:requirement> </my:contract> <my:personResponsible>Max Mustermann</my:personResponsible> </my:mySpecifics> <categories> <category id="c1" code="IC" name="InterCity" description="Fast large city connection" trainUsage="passenger"> <my:mySpecifics version="1.0"> <my:personResponsible>Marie Mustermann</my:personResponsible> </my:mySpecifics> </category> <category id="c2" code="RE" name="RegionalExpress" description="Fast small city connection" trainUsage="passenger"/> </categories> </timetable> </railml>
- The extension element mySpecifics in the element timetable holds the changed contract element. It is based on a railML type and therefore provides the "railML attribute" code for usage instead of the self-defined number element. It further forces the id attribute to be defined. (lines 4-9)
- This example has many in common with the previous one. See that comments, too.
New attributes (Use of xs:anyAttribute)
There are multiple positions where the railML schemas provide the W3C xs:anyAttribute for optional extension by own attributes. That's the case for all elements with the generic railML attributes id, code, name, description... and at other certain positions in the XML tree forseen for extensibility.
<xs:anyAttribute namespace="##other"/>
- namespace="##other" means that the railML schemas force the extensions to be defined in an own new namespace that differs from the railML one. See also Namespace handling
- processContents="strict" (XML Schema default) means that the railML schemas force all extensions to be defined by an XML Schema (*.xsd).
In case of general extensions this feedback should be provided to the railML community e.g. by announcing in the appropriate railML forum or at minimum by mail to the appropriate railML coordinator.
Example for an extension XML Schema defining new attributes without any railML re-use
XML Schema with comments
<?xml version="1.0" encoding="UTF-8"?> <xs:schema targetNamespace="http://www.my-company.com/my-department/" xmlns="http://www.my-company.com/my-department/" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0"> <!-- Person to contact in case of any questions regarding the schema: Max Mustermann, phone: +12-345-67890, mail: max.mustermann@my-company.com --> <xs:attribute name="SAP-Number" type="xs:string"> <xs:annotation> <xs:documentation>Provide our internal SAP number</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute name="variant" type="xs:integer"> <xs:annotation> <xs:documentation>Provide in incremental variant number</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute name="colour" type="colourType"> <xs:annotation> <xs:documentation>Provide the colour of the model</xs:documentation> </xs:annotation> </xs:attribute> <xs:simpleType name="colourType"> <xs:restriction base="xs:string"> <xs:enumeration value="blue"/> <xs:enumeration value="red"/> <xs:enumeration value="yellow"/> </xs:restriction> </xs:simpleType> </xs:schema>
- This example does not re-use railML types. It is fully based on XML Schema types. (lines 6, 12, 25)
- The version attribute in the root element marks the version of the extension schema and should be not confused with the railML version. (line 2)
- It is recommended to use the XML comments for non-content related documentation, e.g. contact information: <!-- ... --> (line 4)
- It is recommended to use the XML Schema possibilities for
- documentation inside the extension schema:
- xs:annotation and xs:documentation (lines 7-9, 13-15, 19-21)
- The type colourType shows how to define simple types that can be used for attributes: xs:simpleType (lines 24-30)
The following XML instance document shows an example how to deploy these extensions within a railML file.
XML Instance with comments
<?xml version="1.0" encoding="UTF-8"?> <railml xmlns="http://www.railml.org/schemas/2011" xmlns:my="http://www.my-company.com/my-department/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.railml.org/schemas/2011 ../schema/railML.xsd http://www.my-company.com/my-department/ usingAnyAttribute.xsd" version="2.1"> <timetable id="tt1" my:SAP-Number="123-abc-456/XY" my:variant="-1"> <categories> <category id="c1" code="IC" name="InterCity" description="Fast large city connection" trainUsage="passenger" my:colour="red"/> <category id="c2" code="RE" name="RegionalExpress" description="Fast small city connection" trainUsage="passenger"/> </categories> </timetable> </railml>
- The element timetable shows the usage of two extension attributes: SAP-Number, variant (line 3)
- The first category element shows the usage of another extension attribute: colour (line 5)
- The second category element shows the absence of the extension attributes. (line 6)
- The extensions are clearly distinguishable from the railML core by defining the appropriate namespace: xmlns:my="http://www.my-company.com/my-department/" (line 2), using the prefix my (lines 3, 5)
Generally, the prefix is a short abbreviation for the domain-specific extension up to three letters.
XML attributes generally occur in no-order. The extension attributes may be mixed with the railML attributes.
Example for an extension XML Schema defining new attributes with some railML re-use
XML Schema with comments
<?xml version="1.0" encoding="UTF-8"?> <xs:schema targetNamespace="http://www.my-company.com/my-department/" xmlns="http://www.my-company.com/my-department/" xmlns:rail="http://www.railml.org/schemas/2011" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0"> <!-- Person to contact in case of any questions regarding the schema: Max Mustermann, phone: +12-345-67890, mail: max.mustermann@my-company.com --> <xs:import namespace="http://www.railml.org/schemas/2011" schemaLocation="../schema/railML.xsd"> <xs:annotation> <xs:documentation>Copyright (c) railML.org; All Rights Reserved.</xs:documentation> <xs:documentation>This work is licensed under a Creative Commons Attribution 2.0 License. http://creativecommons.org/licenses/by/2.0/</xs:documentation> <xs:documentation>For further information see: http://www.railml.org/</xs:documentation> </xs:annotation> </xs:import> <xs:attribute name="SAP-Number" type="rail:tGenericName"> <xs:annotation> <xs:documentation>Provide our internal SAP number</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute name="variant" type="rail:tPositiveCounter"> <xs:annotation> <xs:documentation>Provide in incremental variant number</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute name="colour" type="colourType"> <xs:annotation> <xs:documentation>Provide the colour of the model</xs:documentation> </xs:annotation> </xs:attribute> <xs:simpleType name="colourType"> <xs:restriction base="xs:string"> <xs:enumeration value="blue"/> <xs:enumeration value="red"/> <xs:enumeration value="yellow"/> </xs:restriction> </xs:simpleType> </xs:schema>
- The railML namespace has to be declared in any case where types are reused in the extension: xmlns:rail="http://www.railml.org/schemas/2011" (line 2)
- The railML namespace has further to be imported using the XML Schema rules: xs:import. (lines 6-12)
- The attribute SAP-Number re-uses the railML type tGenericName. (line 14)
- The attribute variant re-uses the railML type tPositiveCounter. (line 20)
- This example has many in common with the previous one. See that comments, too.
The following XML instance document shows an example how to deploy these extensions within a railML file.
XML Instance with comments
<?xml version="1.0" encoding="UTF-8"?> <railml xmlns="http://www.railml.org/schemas/2011" xmlns:my="http://www.my-company.com/my-department/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.railml.org/schemas/2011 ../schema/railML.xsd http://www.my-company.com/my-department/ usingAnyAttributeWithRailML.xsd" version="2.1"> <timetable id="tt1" my:SAP-Number="123-abc-456/XY" my:variant="1"> <categories> <category id="c1" code="IC" name="InterCity" description="Fast large city connection" trainUsage="passenger" my:colour="red"/> <category id="c2" code="RE" name="RegionalExpress" description="Fast small city connection" trainUsage="passenger"/> </categories> </timetable> </railml>
- The changed type of extension attribute SAP-Number in the element timetable has no influence into the XML Instance document. (line 3)
- The changed type of extension attribute variant in the element timetable forces the value to be an non-negative integer. (line 3)
- This example has many in common with the previous one. See that comments, too.
New enumeration value
- In some places railML offers the posssibility to extend the enumeration list by self-defined values following some constraints. The railML type "tOtherEnumerationValue" is included in the pre-defined enumeration list for these cases.
- Good news first: For this technique no XML schema defintion is needed.
- The "new enumeration value" should start with the string
other:
. It should be followed by "word characters" without whitespaces, at minimum two.
example: <places count="10" category="other:foldingSeat"/>
Namespace handling
In any case you 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
xmlns:my="http://www.my-company.com/my-department/"
my
is the abbreviation and http://www.my-company.com/my-department/
is the identifier. The abbreviation must be unique in the railML file but not further. The identifier shall be unique throughout the world… To secure this, often URLs are used as identifiers - as in the example. But 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 there locations; the locations being ‘real’ paths either into 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 first occurrence of any member of the namespace.
If you do not want to use an URL (Uniform Ressource Locator) as an identifier - since there is no real location - you can use any other Uniform Ressource Identifier (URI) 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:deutschebahn:railml_extensions:1.0
or urn:dbnetzag:railml_extensions:1.0
are much better than, say, urn:db:railml_extensions:1.0
.
Conclusion:
- 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!
When using :any
and what to respect before starting?
|
Please, pay attention to our guideline for participating in the development process.
If you intend to define a new any
-element, please, research carefully, whether there already exists a solution to your problem. We want to avoid duplications, as the tend to make the schema incomprehensive and cause avoidable efforts. Duplicates will not be certified and will therefore generally be excluded from data exchange.
- Read this wiki and examine the schema carefully whether there exists a solution already.
- Publish your intention in the railML®-Forum. 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
- Before starting, inform the coordinator, as to provide for a solution that fits into the context.