ISO 10303-21, “Part 21”, defines the clear text encoding of a STEP file: how data that is described by an EXPRESS schema is written as text. It does not define the schema, so a file is only as meaningful as the schema it names (see Schemas and core entities). The standard is sold by ISO; this page restates the rules from the third edition’s final text as STEP Tools publishes it (document ISO TC 184/SC4/WG11 N304, dated 2015-07-30) in its own words. The earlier editions are covered where the text says how they differ.
File structure
An exchange structure is a sequential file of text. In order:
ISO-10303-21;- The header section,
HEADER;…ENDSEC;(required) - An optional anchor section,
ANCHOR;…ENDSEC; - An optional reference section,
REFERENCE;…ENDSEC; - Any number of data sections,
DATA;orDATA(…);…ENDSEC; END-ISO-10303-21;- Any number of signature sections,
SIGNATURE;…ENDSEC;, after the closing token
The data section is optional in the third edition, so a file can consist only of forwarding references. A file may be compressed in a ZIP archive (see below).
ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('example'),'2;1');
FILE_NAME('part.stp','2026-01-01T12:00:00',('author'),('org'),'preproc','system','');
FILE_SCHEMA(('CONFIG_CONTROL_DESIGN'));
ENDSEC;
DATA;
#1=CARTESIAN_POINT('',(0.,0.,0.));
#2=DIRECTION('',(0.,0.,1.));
#3=DIRECTION('',(1.,0.,0.));
#4=AXIS2_PLACEMENT_3D('',#1,#2,#3);
ENDSEC;
END-ISO-10303-21;
Characters and token separators
- The alphabet is the Unicode code points U+0020 to U+007E and U+0080 to U+10FFFF, written in UTF-8. Octets outside the encoded ranges, including line feeds, carriage returns, tabs and form feeds, are ignored when processing the file, so a line break may appear anywhere, even inside a token. (Editions 1 and 2 used only the ASCII range, with ISO 8859 characters reached through string directives.)
- Only the space separates tokens, apart from comments and the print directives
\N\(newline) and\F\(form feed). Any number of separators may appear wherever one may. - A comment starts with
/*and ends with*/. They do not nest. - The print directives may appear wherever a separator may, and inside strings and binaries (where they add nothing to the value), but not inside a URI, the anchor section or the reference section.
Tokens
| Token | Form | Examples and rules |
|---|---|---|
| Keyword | Capital letters, digits and low line, starting with a letter | CARTESIAN_POINT. A leading ! (at most once, first) makes a user-defined keyword, whose meaning is agreed between the partners (!MYCURVE) |
| Integer | Optional sign and digits, base 10 | 16, +12, -349, 012 (12). Not 26 54, 32.0 or + 12 |
| Real | Optional sign, one or more digits, a full stop, zero or more digits, then optionally E with an optional sign and digits | 1.5, 2., 0.E25, -32.178E+02. Not .5, 1, 1E05, 3.E or 1,000.00. No precision is conveyed |
| String | Apostrophe, characters, apostrophe | An apostrophe inside is doubled, a reverse solidus is doubled, '' is the empty string. Directives are listed below. The stored string, including its apostrophes, is at most 32 769 octets |
| Entity instance name | # and digits, not all zero | #12; leading zeros are insignificant (#001 is #1). Forward and backward references are allowed |
| Value instance name | @ and digits, not all zero | Defined only in the reference section. Its number may not equal an entity instance name’s number, so a URI fragment of digits is unambiguous |
| Constant entity name | #, a capital letter, then capitals and digits | #INCH: refers to an entity constant defined in the schema (the first schema if there are several). May be used on the right-hand side only |
| Constant value name | @, a capital letter, then capitals and digits | @PI: refers to a value constant in the schema. Right-hand side only |
| Enumeration | Full stop, capital letter, capitals and digits, full stop | .STEEL.. BOOLEAN uses .T. and .F.; LOGICAL adds .U. (unknown) |
| Binary | Double quotes around hexadecimal digits, the first digit being 0 to 3 | See below |
| Anchor name | < URI fragment > | At least one character must not be a digit. A UUID is allowed |
| Resource | < URI > | <picture.jpg>, <http://example.com/a.stp#shape> |
| Tag name | Letter, then letters and digits | Used in anchor tags |
$ | Special token | The attribute has no value (null) |
* | Special token | The attribute is a redeclared derived attribute and its value follows from the schema’s rules |
Punctuation is the semicolon, parentheses, comma and solidus. A list is
( … ) with parameters separated by commas, can be empty and nests to any
depth. A typed parameter is a keyword followed by a parameter in parentheses; it
appears where the schema uses a SELECT type, for example
#1=STEEL_BAR(FLOATINGNUMBER(77.0),MEASURED_MASS(13.25));.
String control directives
Characters outside U+0020 to U+007E may be written directly in UTF-8 or, for
compatibility with the older editions, with a directive. A string may contain no raw
control characters, so U+0000 to U+001F and U+007F must use \X\.
| Directive | Meaning |
|---|---|
\S\c | The character whose code is that of c plus 128, in the ISO 8859 part chosen by the last \P directive in the string (part 1 if none). '\S\D' is a capital A with diaeresis, (U+00C4, code 0x44 + 0x80) |
\PL\ | Selects ISO 8859 part 1 to 9 for the following \S\ directives in this string only: A is part 1, B part 2, and so on up to I |
\X2\ hhhh … \X0\ | Each group of four hexadecimal digits is one UCS code point (16-bit) |
\X4\ hhhhhhhh … \X0\ | Each group of eight hexadecimal digits is one code point (32-bit; the first two digits are always zero) |
\X\hh | One code point U+0000 to U+00FF. Required for U+0000 to U+001F and U+007F |
\N\, \F\ | Print control only: newline and form feed, which are not part of the string’s value |
'Don''t' Don't
'\X2\03C0\X0\' π (U+03C0)
'\X4\001F600\X0\' U+1F600
'see \X\A7 4.1' see § 4.1
'line one\X\0Aline two' line one, a line feed, line two
Binary encoding
A binary value of p bits is left-padded with n zero bits (0 to 3) to a multiple of
four, and written as one hexadecimal digit giving n followed by the hexadecimal digits of
the padded bits, in double quotes. So the empty value is "0", a single 0 bit is
"30", a single 1 bit is "31", 111011 is "23B" and
100100101010 is "092A".
Header section
The header holds three entities that must appear in this order, then any of the optional
ones, then user-defined header entities. Each is written as
KEYWORD(parameters);.
| Entity | Attributes | Meaning |
|---|---|---|
FILE_DESCRIPTION | description: list of one or more strings; implementation_level: string | Informal description of the contents, and the conformance level (below) |
FILE_NAME | name; time_stamp; author (list); organization (list); preprocessor_version; originating_system; authorization (all strings except the lists) | Human-readable information. Only name and time_stamp are defined by the standard: the name identifies the exchange structure (an object identifier is recommended) and the time stamp is ISO 8601 date and time joined by T, with optional zone, as in 1993-04-12T15:27:46-05:00 |
FILE_SCHEMA | schema_identifiers: list of strings | The EXPRESS schemas that govern the data. Names are upper case, optionally followed by an object identifier in braces: 'AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 }' |
SCHEMA_POPULATION | external_file_identifications: a list of lists of one to three strings | Other files whose instances belong to the schema population: an address (URI), an optional time stamp and an optional Base64 message digest, with $ for a missing one. At most one per file |
FILE_POPULATION | governing_schema; determination_method; governed_sections (optional set of section names) | Selects instances for conformance to one schema. $ means all data sections |
SECTION_LANGUAGE | section (optional); default_language | The language of strings in a data section, as an ISO 639-2 alpha-3 code such as 'eng'. With $ as the section it is the default for all |
SECTION_CONTEXT | section (optional); context_identifiers: list of strings | Context tags for a data section, for example application protocol conformance classes |
Implementation level
| Value | Meaning |
|---|---|
'4;1' | Third edition, syntactical conformance class 1: no anchor, reference or signature sections |
'4;2' | Class 2: has a reference section, or is a multi-file ZIP structure |
'4;3' | Class 3: defines value instances, references EXPRESS constants or defines functionality with ECMAScript |
'3;1' | Second edition (2002) class 1. Allowed only if there is no anchor, reference or signature section, no SCHEMA_POPULATION, no EXPRESS constants, and non-ASCII characters are written only with \X2\ and \X4\ |
'2;1' | First edition (1994) class 1: additionally a single data section with no parameter list after DATA, no FILE_POPULATION, SECTION_LANGUAGE or SECTION_CONTEXT, and no short names for enumeration values |
'2;2', '3;2' | Used by earlier editions for an external mapping of all entity instances; not valid values now |
The general form is “v;cc”, the edition number and the conformance class.
Data sections
- With a single data section,
DATA;is enough, and FILE_SCHEMA names exactly one schema, which governs it. With several, each isDATA('name',('SCHEMA'));: a unique section name, and a list of exactly one string naming a schema from FILE_SCHEMA. - Each entity instance is
#n=KEYWORD(attributes);, with a unique name in the whole file. Order does not matter, and a name may be used before it is defined, even in another data section. - The attributes appear in the order of the EXPRESS declaration: for a simple instance the entity’s own explicit attributes; inherited and derived parts are covered below.
- A user-defined instance uses a
!keyword and an agreed layout (#12=!MYCURVE(0.,0.,0.,1.,$,$,$);). The standard recommends a separate schema instead.
How EXPRESS types are written
| EXPRESS | Written as |
|---|---|
| INTEGER, REAL, NUMBER | An integer, or a real for REAL and NUMBER; precision and string width do not change the encoding |
| STRING, BINARY | A string, a binary |
| BOOLEAN, LOGICAL, ENUMERATION | An enumeration: .T. and .F., with .U. for LOGICAL |
| LIST, ARRAY, SET, BAG | A list. A multidimensional array is a list of lists with the last index varying fastest. Empty is (). An array element or optional attribute with no value is $ |
| SELECT | A typed parameter naming the chosen defined type, applied recursively for nested selects |
| Defined TYPE | As its underlying type |
| Entity-valued attribute | The instance name of the referenced instance (#2=XXX(#1,#3);) |
| OPTIONAL attribute with no value | $, never an empty list |
| Derived, redeclared as DERIVE | * at that position |
| INVERSE, FUNCTION, PROCEDURE, RULE, WHERE rules, REMARKS, SCHEMA | Not written. A reference to an EXPRESS CONSTANT is a constant name |
Entity type names are written upper case, using the schema’s published short names if it defines them.
Subtypes and complex instances
An instance that belongs to a subtype is complex. One of two mappings applies, decided per instance. Find the entity types in the instance’s evaluated set that have no subtype in that set (the leaf types).
- Internal mapping, when there is exactly one leaf type: an ordinary record whose keyword is the leaf type and whose parameters are the inherited attributes first (the supertypes in the order of the SUBTYPE OF clause, the highest supertype first, repeated supertypes only once), then the leaf’s own.
- External mapping, when there are several leaf types: a parenthesised sequence of simple records, one per entity type of the instance, in ascending order of type name (compared as upper-case letters and digits by octet value), each carrying only that type’s own explicit attributes. Example:
#5=(LENGTH_UNIT()NAMED_UNIT(*)SI_UNIT(.MILLI.,.METRE.));.
Anchor, reference and signature sections
- Anchor section. Each entry gives an external name to an instance or value:
<name> = item {tag:item};. The item may be$, an integer, real, string, enumeration or binary, an instance name, a resource, or a (nested) list of these. Names are unique in the file and may be UUIDs. A tag,{preparation:<WELD_DC.XML>}, attaches extra information that is outside the information model. The section comes after the header and before any reference, data or signature section. - Reference section. Entries are
#10 = <uri>;or@20 = <uri>;, binding an instance or value name to something in another file. The resource may be a whole file, a fragment that is an anchor (including a UUID), a fragment in the same file, a file in another format, or a fragment of digits, which means an instance name from an older-edition file. Each name appears once and is not also defined in a data section. - Signature section.
SIGNATURE;, Base64 text andENDSEC;. The content is a Cryptographic Message Syntax (RFC 5652) signature with external content, covering everything before theSIGNATURE;token including earlier signatures; only characters of the basic alphabet go into the digest.
ANCHOR;
<82ff3c50-3610-11e5-a2cb-0800200c9a66> = #10;
<bb2ac46e-3610-11e5-a151-feff819cdc9f> = (1.1, 2.1, 3.1);
<1231ea63-d573-4d50-81f3-8bb0e9c1cbf5> = #10 {ratio:196.73};
ENDSEC;
REFERENCE;
#10 = <http://example.com/product.stp#shape>;
@70 = <http://example.com/product.stp#value>;
ENDSEC;
ZIP archives and directories
A file may be stored in a ZIP archive written with PKZIP 2.04g compression (no
encryption, Unicode file names or Deflate64). The archive’s root, which must exist for it to
conform, is a file named ISO-10303.p21. Other files are subsidiaries: further
exchange structures, further archives or ancillary data such as pictures. Relative
addresses resolve inside the archive and may not point outside it, and only the root can
be referenced from outside, so subsidiaries are exposed through anchors in the root. A
directory containing ISO-10303.p21 is treated the same way.
Not on this page
- Annexes of the standard on tape and diskette transport, the PICS proforma, multiple-schema population methods (annex E) and the ECMAScript binding for the anchor section (annex F).
- The grammar in Wirth syntax notation, which is the standard’s own table; the tokens table above is its content.
- Part 28 XML encoding and Part 26 binary encoding of ISO 10303, which are other encodings of the same schemas.
Sources
- ISO 10303-21, third edition, ISO TC 184/SC4/WG11 N304 – the final text, dated 2015-07-30 and published by STEP Tools. It is ISO copyright material: this page restates it and does not reproduce it. Clauses 3 to 14 and annexes A and B