Dev:UsingAny: Difference between revisions

From railML 2 Wiki
Jump to navigation Jump to search
[checked revision][checked revision]
(template:external)
(template:external)
Line 413: Line 413:
Namespace identifier and abbreviation must be declared with the xmlns:… attribute before being used. The declaration is typically set into the root element (<nowiki><railml></nowiki>) but may also be set in any sub-element before first occurrence of any member of the namespace.
Namespace identifier and abbreviation must be declared with the xmlns:… attribute before being used. The declaration is typically set into the root element (<nowiki><railml></nowiki>) 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 ([https://en.wikipedia.org/wiki/Uniform_resource_locator Uniform Ressource Locator]) as an identifier - since there is no real location - you can use any other [https://en.wikipedia.org/wiki/Uniform_resource_identifier 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:<br>
If you do not want to use an URL ({{external|https://en.wikipedia.org/wiki/Uniform_resource_locator|Uniform Ressource Locator}}) as an identifier - since there is no real location - you can use any other {{external|https://en.wikipedia.org/wiki/Uniform_resource_identifier|Uniform Ressource Identifier (URI)}} instead. To show that your identifier is virtual throughout, you should let it start with <nowiki>“urn:”</nowiki> instead of “http:” (urn is for Uniform Ressource Name) as:<br>
:<code>xmlns:my="urn:MyCompany:MyDepartment:MyBranch:MyBureau:MyRailML_extensions:Version1.0:MyProject"</code>
:<code>xmlns:my="urn:MyCompany:MyDepartment:MyBranch:MyBureau:MyRailML_extensions:Version1.0:MyProject"</code>



Revision as of 15:35, 14 January 2018

There are multiple possibilities for extending the officially published railML schemas by own needs, e.g. elements, attributes and enumeration values.

WarningSignpost blue.png Important: Before starting using any or anyAttribute please read carefully and understand the first section!

The following sections show how to achieve this in a valid form.

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

If you intend to define a new any-element, please, research carefully, whether there already exists a solution to your data exchange problem. As data interoperability is the aim of the railML®, same data content and use case shall be exchanged in the same element and attribute. Therefore we have to avoid duplications, as they tend to make the 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:
  1. If the element already exists, the redundancy will very likely get apparent before you have taken too much effort.
  2. The community can support you. Maybe others have the same demand and a new railML element or attribute can be added to the scheme.

Please, pay attention to our guideline for participating in the development process in addition.

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

There are multiple positions where the railML schemas provide the W3C xs:any element (external link) 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 minimum 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="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: <!-- ... --> (external link; line 4)
  • It is recommended to use the XML Schema possibilities for documentation inside the extension schema: xs:annotation and xs:documentation (external link; lines 7-9, 13-15, 18-20, 30-32, 35-37)
  • The elements mySpecifics and contract show how to define sub-trees: xs:complexType (external link; 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="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 (external link; 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 those comments, too.

New attributes (Use of xs:anyAttribute)

There are multiple positions where the railML schemas provide the W3C xs:anyAttribute (external link) 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="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: <!-- ... --> (external link; line 4)
  • It is recommended to use the XML Schema possibilities for
  • documentation inside the extension schema:
  • xs:annotation and xs:documentation (external link; lines 7-9, 13-15, 19-21)
  • The type colourType shows how to define simple types that can be used for attributes: xs:simpleType (external link; 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 (external link; 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 (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:

xmlns:my="urn:MyCompany:MyDepartment:MyBranch:MyBureau:MyRailML_extensions:Version1.0:MyProject"

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!