Dev:UsingAny

From railML 3 Wiki
Jump to navigation Jump to search

This article explains how to extend the railML® 2 and railML® 3.1 schema using

  • the xs:any-element and
  • the xs:anyAttribute

Consequently, this is a subtopic of dev:Extending railML.

💡 Important: Before starting using any or anyAttribute please read carefully and understand the first section!  

When using xs:any / anyAttribute and what to respect before starting?

New elements, respectively sub-trees (Use of xs:any)

There are multiple positions where the railML® schema provides the W3C xs:any element for optional extensions by own elements, respectively 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 (link to the railML® website) or at least by mail to the appropriate railML® coordinator (link to the railML® website).

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="https://www.my-company.com/my-department/" xmlns="https://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 once. (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="https://www.my-company.com/my-department/" 
        xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://www.railml.org/schemas/2011 https://schemas.railml.org/2011/railML-2.1/railML.xsd https://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="https://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 of 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="https://www.my-company.com/my-department/" xmlns="https://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="https://schemas.railml.org/2011/railML-2.1/railML.xsd">
    <xs:annotation>
      <xs:documentation>Copyright (c) railML.org; All Rights Reserved.</xs:documentation>
      <xs:documentation>For license see: https://www.railml.org/en/user/licence.html/</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 those comments, too.

The following XML instance document shows an example of 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="https://www.my-company.com/my-department/" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://www.railml.org/schemas/2011 https://schemas.railml.org/2011/railML-2.1/railML.xsd https://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 those 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 (link to the railML® website) or at minimum by mail to the appropriate railML coordinator (link to the railML® website).

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="https://www.my-company.com/my-department/" xmlns="https://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="https://www.my-company.com/my-department/" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://www.railml.org/schemas/2011 https://schemas.railml.org/2011/railML-2.1/railML.xsd https://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="https://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="https://www.my-company.com/my-department/" xmlns="https://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="https://schemas.railml.org/2011/railML-2.1/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. https://creativecommons.org/licenses/by/2.0/</xs:documentation>
      <xs:documentation>For further information see: https://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="https://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 those 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="https://www.my-company.com/my-department/" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://www.railml.org/schemas/2011 https://schemas.railml.org/2011/railML-2.1/railML.xsd https://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 those comments, too.

New enumeration value (Use of tOtherEnumerationValue)

  • In some places railML® offers the possibility 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 shall be followed by at least two "word characters"[1]. A "word character" is any unicode letter, number or symbol, excluding any punctuation, separators or whitespace. Notably, hyphen (-) and underscore (_) are not allowed. Best practice is to use only the letters A–Z/a–z and the digits 0–9, with camelCase for compound words that normally include spaces or hyphens.

example: <places count="10" category="other:foldingSeat"/>

definition of tOtherEnumerationValue
<xs:simpleType name="tOtherEnumerationValue">
  <xs:annotation>
    <xs:documentation>an arbitrary string starting with 'other:' followed by at least two letters and/or digits, for extending railML enumeration lists</xs:documentation>
  </xs:annotation>
  <xs:restriction base="xs:string">
    <xs:pattern value="other:\w{2,}"/>
  </xs:restriction>
</xs:simpleType>