3D PLM PPR Hub Open Gateway |
PDM Object Hub |
Express-X MappingHow to create a mapping to Express-X |
Use Case |
This article will introduce the basic functionalities of Express-X enabling you to perform an Express-X mapping.
Express-X is destined to become the standard conversion tool between two Express schemas and to become a part of the STEP standard. The Express-X manual dated August 21, 1996 has reference number ISO TCI184/SC4/WG11/N002.
The conversion should be specified in a file of which the syntax is similar to that of an Express file. In the current implementation, the file is compiled during the preliminary phase of the C++ code generation.
Suppose you have two Express schemas defining the same data in two different manners. You will then define a mapping schema from the first (referred to as the base schema) to the second (referred to as the view schema) by declaring for each schema a schema instance identifier that will correspond to an SDAI model.
With the following syntax, you can define more than two schema instances if necessary.
SCHEMA_MAP schema_name GLOBAL DECLARE MyView INSTANCE OF schema_view DECLARE MyBase INSTANCE OF schema_base END_GLOBAL; (* entity mapping *) END_SCHEMA_MAP;
Inside the SCHEMA_MAP block, you declare a mapping from the entity entb of the schema MyBase to the target entity entv as follows:
VIEW instv : MyView::entv; FROM (instb : MyBase::entb) WHEN TRUE; (* creation condition *) BEGIN_VIEW ... (* Attribute mapping *) END_VIEW;
In the above syntax, instv and instb are two arbitrary identifiers the visibility of which is limited to the block VIEW ... END_VIEW. In the FROM statement you can indicate several base instances by separating the parameters using commas.
Inside the BEGIN_VIEW ... END_VIEW block, you declare the matching between entity attributes of the base view with:
instv.attrv := instb.attrb;
You can use an attribute referenced indirectly by the entity by stating a path of type attr1.attr2, which means that the attribute attr1 references the instance attribute attr2.
If you want to convert an entity type attribute, you must specify the target entity in brackets. The way this conversion will be implemented must also be stated in a VIEW command.
For example:
attrv := {entv} attrb; and (in another location) VIEW instv : MyView::entv; FROM (instb : MyBase::entb) ...
If there are several VIEW commands corresponding to an entity, the ambiguity can be resolved using the FOR parameter which specifies a unique identifier for the view:
attrv := {viewA} attrb;
If you have:
VIEW viewA FOR instv : MyView::entv; VIEW viewB FOR instv : MyView::entv;
If the real type of the attribute attrb may vary (in the case of a SELECT or a super-type), you must add a series of tests:
IF (attrb IS entb) attrv := {entv} attrb; END_IF;
This mechanism guarantees that the corresponding entity will be created only once in the view model even if it is referenced by several instances in the base model.
NEW entv.attrv;
entv.attrv += value;
entv.attrv[i] := value;
where i
is a constant or a loop variable.
In place of the source attribute, you can state a real constant, an integer or a string (between ").
The COMPOSE command enables you to establish, after having created all the view instances, relations between view instances that were not possible previously.
You can also update the base (in an asynchronous manner) in the event of a view modification.
The syntax is the following:
COMPOSE (instv : MyView::entv) [ FROM (instv2 : MyView::entv2, ...) ] (* optional *) WHEN TRUE; BEGIN_COMPOSE ... END_COMPOSE;
You can use the standard Express functions: =, <, >, NOT, AND, OR, IN, IS.
Dassault Systemes Extension:
You can define your own functions by specifying a signature:
SdaiPrimitiveH f(const SdaiPrimitiveH&);
or
SdaiPrimitiveH f(const SdaiPrimitiveH&, const SdaiPrimitiveH&);
Each identifier of a non-standard function will be considered as user-defined.
You can add an integration on an entity in a VIEW by adding a FROM command followed with BEGIN ... END:
FROM (instv2 : MyView::entv2) WHEN instv2 IS entv3; BEGIN ... END;
You can define a conditional behavior:
if ( condition ) THEN x :=y; ED_IF;
If a condition is defined by a user function, the result should be an SdaiPrimitiveH of type SdaiLog.
You can define a loop as follows:
REPEAT i := 1 to n; ... END_REPEAT;
You can instantiate in the view schema entities that do not correspond to any entity of the base schema by using the following syntax:
#MyView::person = Man('Smithee','Alan', 175,72.0);
This instance can be referenced in the mapping with #person.
You can define a complex entity by separating the components with a + (you should also list every entity supertypes).
For example:
VIEW x : sch::a+b; or x := {a+b} y;
You can declare global variables with the following syntax:
VarString : String ;
This instance can be referenced in the mapping with #person.
When the view called by a cast contains several source entities, you should designate them in the cast call.
For example:
attrv := {MyView::ent} (attrb,attrc);
If you want to call:
VIEW instv : MyView::entv; FROM (instb : MyBase::entb, instc : MyBase::entc)
If you want to perform a compilation, you have to define a file tree.
The Express-X mapping must be in a module.
You will then have to launch the mkmk tool.
SCHEMA AP203AIM ; ENTITY product ; id : STRING ; name : STRING ; END_ENTITY; -- product ENTITY product_definition ; description : STRING ; of_product : product ; END_ENTITY; -- product_definition ENTITY assembly_component_usage ; description : STRING; relating_product_definition : product_definition; related_product_definition : product_definition; reference_designator : OPTIONAL STRING; END_ENTITY; -- product_definition_usage END_SCHEMA
SCHEMA AP203ARM ; ENTITY part_identification ; part_number : STRING ; (* identifier *) part_BOM : STRING ; (* label; *) description : STRING ; (* text; *) IEND_ETITY ENTITY bill_of_material; reference_designator : STRING ; (* identifier; *) is_the_assembly_for : part_identification; is_used_as_a_component_in: part_identification; END_ENTITY; -- bil_of_material END_SCHEMA
SCHEMA_MAP ARM; GLOBAL DECLARE arm INSTANCE OF AP203ARM ; (* VIEW *) DECLARE arm INSTANCE OF AP203AIM ; (* BASE *) END_GLOBAL; VIEW pid : arm::part_identification; FROM ( pd : aim::product_definition) WHEN TRUE; BEGIN_VIEW pid.part_number := pd.creation_of_product.id ; pid.part_bill_of_material := pd.creation_of_product.name ; pid.revision_letter := pd.creation.id ; pid.description := 'unknown' ; -- constant END_VIEW ; VIEW bom : arm::bill_of_material; FROM (acu : aim::assembly_component_usage) WHEN TRUE; BEGIN_VIEW bom.reference_designator := acu.reference_designator ; bom.description := acu.description ; bom.is_used_as_a_component_in := { part identification } acu.related_product_definition ; -- cast !! bom.is_the_assembly_for := { part_identification } acu.relating_product_definition ; END_VIEW ; END_SCHEM_MAP
#1=product('Wheel','product 001') ; #2=product('Window','product 002') ; #3=product('Tyre','product 003') ; #4=product_definition('prod def 001',#1) ; #5=product_definition('prod def 002', #2) ; #6=product_definition('prod def 003',#3) ; #7=assembly_component_use('descript 001', #4, #6, 'Front'); #8=assembly_component_use('descript 002', #4, #6, 'Back'); #9=assembly_component_use('descript 003', #6, #5, 'Left');
#1=bill_of_material('Front','descript 001',#2,#4); #5=bill_of_material('Back','descript 002',#2,#4); #6=bill_of_material('Left','descript 003',#4,#3); #2=part_identification('Wheel','product 001','prod def 001'); #3=part_identification('Window','product 002','prod def 002'); #4=part_identification('Tyre','product 003','prod def 003');
Copyright © 1994-2002, Dassault Systèmes. All rights reserved.