Tailoring Mechanisms

Disclaimer: This page or section is currently under review by the community.

The content of this page or section can be subject to change at any time. If you find any issues or if you have any review comments please drop us an issue on the PROSTEP JIRA.

This page or section resolves KBLFRM-989

There are two ways to tailor the VEC schema according to your own needs in a compatible way and create your own process, tool or company specific VEC schema (which is still a valid VEC):

  1. New literals can be added to open enumerations (see Open and Closed Enumerations)
  2. With “Schema Filtering” the schema can be made more restrictive (Less allowed classes, attributes etc.).

In order to remain compatible with the VEC, both approaches require that the changes are in a way, so that a file that is validated against the custom Schema must also be valid against the Schema of the Standard.

This Implementation Guideline explains how these modifications can be achieved in an efficient way and is based on XSLT. XSLT is a useful technology, when:

  • you want to modify XML data,
  • you can define the modification based on rules,
  • the general structure of your result is close to the input,
  • and performance is not critical.

Therefore it is the perfect solution for this case, where we want to modify the XML Schema of the VEC at very specific locations while keeping the rest unchanged.

Open Enumerations

Open Enumerations enable users to create company specific schemes by adding custom enumeration literals to the VEC, while preserving the possibility to do schema validation.

1. Prerequisites

2. Define new literals in enum-literals.xsl

The enum-literals.xml file contains examples on how to add custom enumerations.

<?xml version="1.0" encoding="UTF-8"?>
<enum-profile>
    <enum type="WireReceptionType">
        <literal name="MyExampleLiteral">
             My example description with html elements <br/>
        </literal>
        <literal name="MyExampleLiteral2" />
    </enum>
    <enum type="WireLengthType">
        <literal name="MyExampleLiteral3">
             My second example description
        </literal>
    </enum>
</enum-profile>

This example adds a literal with the name “MyExampleLiteral” to “WireReceptionType” with a description (Note that its possible to include html tags) and a literal without a description named “MyExampleLiteral2”. It also adds “MyExampleLiteral3” to “WireLengthType”.

If a new VEC version is released, this file can be used recreate an updated company specific scheme (without having to repeat many manual changes).

3. Run Generation

Generation Process Overview

With XSLT2 processing its possible to merge the enum-literals.xsl file with the vec-strict file by using the logic defined in vec-open-enum-compiler.xsl. NOTE: enum-literals.xml and vec-open-enum-compiler.xsl must be placed in the same directory.

Run the transformation with Saxon HE for Java:

java -cp /path/to/saxon.jar net.sf.saxon.Transform \
    -xsl:/path/to/vec-open-enum-compiler.xsl \
    -s:/path/to/vec_1.2.0-strict.xsd \
    -o:/path/to/result.xml

Schema Filtering

The VEC is a comprehensive model with a variety of classes and attributes. In very few cases all of them are needed at the same time. For this reason it may be desirable to restrict the number of valid schema elements for specific interfaces. Schema Filtering can be useful in these cases.

For example, an interface for the exchange of UsageNodes would only require a handful of VEC core classes. Another scenario might be that you want to prohibit the use of CustomProperty in your own process. Many scenarios are conceivable, in the core it always burns down to limiting the power of the VEC purposefully to achieve a better controllability for certain use cases and interfaces.

Since the scenario of Schema Filtering is more complex and less straight forward, than the Open Enumerations scenario, the following section just provides an idea for a possible approach and not a “ready-to-use” solution.

The basic idea here is, that an XSLT script simply removes all unnecessary elements and leaves the rest unchanged. You can use either a positive or negative filter approach. In our example, we use a negative filter list (all elements on the list are removed). When removing a class it is not sufficient to only remove the class itself. All usages of the class must be removed as well. A class that has mandatory usages by other classes, can not be removed unless all usages are removed recursively till an optional point is reached.

The file vec-tailor-schema.xsl contains an example on how to remove the Transformation2D from the VEC scheme. The following snippet shows the relevant parts only. The rest of the XSLT script is known known as identity transformation (copy of the source into the destination without changes).

The first line removes the class itself. The second line removes all optional attributes with the type Transformation2D. If you validate the resulting schema you can easily check if the Transformation2D has any mandatory usage that have been overlooked (it has not).

    ...
    <xsl:template match="xs:complexType[@name='Transformation2D']" />

    <xsl:template match="xs:element[@type='vec:Transformation2D' and @minOccurs=0]" />
    ...
Illustrating Model Snippet

Unfortunately IDREF attributes cannot be handled in this fashion automatically, but have to be checked manually. The figure on the right side displays the occurrenceOrUsage association between OccurrenceOrUsageViewItem2D and OccurrenceOrUsage. Associations are translated into IDREF or IDREFS in the XML Schema, in contrast to aggregations that are translated into contained xs:element (compare Mapping of the VEC Model to XML schema definition (XSD)). The XML Schema representation of the association is the following:

<xs:complexType name="OccurrenceOrUsageViewItem2D">
    <xs:complexContent>
        <xs:extension base="vec:ExtendableElement">
        <xs:sequence>
            ...
            <xs:element name="OccurrenceOrUsage" type="xs:IDREFS" minOccurs="0"/>
            ...
        </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

That means a filtering rule cannot be formulated based on the target type of the association, as this type unknown in the XSD (in contrast to contained elements). Therefore a filtering rule must be more specific by explicitly addressing each relevant association, like this:

    ...
    <xsl:template match="xs:element[@name='OccurrenceOrUsage' and 
        ancestor::xs:complexType[@name='OccurrenceOrUsageViewItem2D']]" />
    ...
Note: Make sure that the resulting schema remains compatible with the standard (XML Schema and Model Specification):

  • Do not remove elements that are mandatory!
  • Take extra care of usages via IDREF associations. These have to be checked in the model since the XML Schema is typeless for those associations.