As mentioned previously, both the schema and business data are stored in i-models in a Bentley specific XML format. This format is referred to as ECXML, where EC stands for Engineering Content.
The schemas authored by the Bentley Class Editor are saved in the ECXML format. This same format is used when writing and reading instance data from a DGN file. Specifically, the data is written and read as XML fragments using methods associated with the XmlInstanceApi. These XML fragments must conform to the schema(s) that will be embedded in the i-models during publishing.
Some of the classes presented earlier and associated instance data are shown below in the ECXML format. The first is the Company and related Location class. Recall, the Location class represents a complex data type used to define the HeadQuarters and OfficeLocations properties of the Company class.
<
ECClass typeName=
"Company" isDomainClass=
"True">
<ECCustomAttributes>
<InstanceLabelSpecification xmlns="Bentley_Standard_CustomAttributes.01.00">
<PropertyName>Name</PropertyName>
</InstanceLabelSpecification>
</ECCustomAttributes>
<
ECProperty propertyName=
"Name" typeName=
"string" />
<
ECProperty propertyName=
"NumberOfEmployees" typeName=
"int" displayLabel=
"Number Of Employees" />
<ECArrayProperty propertyName="Products" typeName="string" minOccurs="0" maxOccurs="unbounded" />
<ECStructProperty propertyName="HeadQuarters" typeName="Location" />
<ECArrayProperty propertyName="OfficeLocations" typeName="Location" description="Office Locations"
displayLabel="Office Locations" minOccurs="0" maxOccurs="unbounded" isStruct="True" />
<
ECProperty propertyName=
"ContactAddress" typeName=
"string" displayLabel=
"Contact Address">
<ECCustomAttributes>
<CalculatedECPropertySpecification xmlns="Bentley_Standard_CustomAttributes.01.00">
<ECExpression>this.Name & ", " & this["HeadQuarters"].Street & ", " & this["HeadQuarters"].City
& ", & this["HeadQuarters"].State & ", " & this["HeadQuarters"].Country & ", " &
this["HeadQuarters"].Zip
</ECExpression>
<FailureValue>-</FailureValue>
<RequiredSymbolSets />
</CalculatedECPropertySpecification>
</ECCustomAttributes>
</ECProperty>
</ECClass>
<ECClass typeName="Location
" isStruct="True" isDomainClass="True">
<ECProperty propertyName="Street" typeName="string" />
<ECProperty propertyName="City" typeName="string" />
<ECProperty propertyName="State" typeName="string" />
<ECProperty propertyName="Country" typeName="string" />
<ECProperty propertyName="Zip" typeName="string" displayLabel="Zip Code" />
</ECClass>
An example of the instance data that might be written for a Company business object is shown below.
<Company instanceID= 1" xmlns= Company.02.00 >
<Name >Bentley Systems Inc.</Name>
<NumberOfEmployees>2700</NumberOfEmployees>
<Products>
<string>MicroStation</string>
<string>ProjectWise</string>
<string>AssetWise</string>
<string>Bridge Design and Engineering</string>
<string>Building Analysis and Design</string>
<string>Civil Construction</string>
<string>Plant Design and Engineering</string>
</Products>
<HeadQuarters>
<Location>
<Street>685 Stockton Drive</Street>
<City>Exton</City>
<State>PA</State>
<Country>United States</Country>
<Zip>19341</Zip>
</Location>
</HeadQuarters>
<OfficeLocations>
<Location>
<Street>No. 81 Jianguo Road</Street>
<City>Beijing</City>
<Country>China</Country>
<Zip>100025</Zip>
</Location>
<Location>
<Street>Svitrigailos g. 11H</Street>
<City>Vilnuis</City>
<Country>Lithuania</Country>
<Zip>03228</Zip>
</Location>
</OfficeLocations>
</Company>
Notice, an instanceID and XML namespace xmlns are defined for the instance. A unique instanceID must be provided for every instance of a particular class. The name of the schema from which the class is defined must also be provided. Also, notice a value is not supplied for the ContactAddress property, since its value is calculated. The calculation will be performed and the resultant value assigned to property when the i-model is opened and the instance is loaded into memory. Finally, notice how values are assigned to the Products and OfficeLocations property arrays. The Employee class and sample instance data are shown next.
<
ECClass typeName=
"Employee" isDomainClass=
"True">
<ECCustomAttributes>
<InstanceLabelSpecification xmlns="Bentley_Standard_CustomAttributes.01.00">
<PropertyName>FullName</PropertyName>
</InstanceLabelSpecification>
</ECCustomAttributes>
<
ECProperty propertyName=
"FirstName" typeName=
"string" displayLabel=
"First Name />
<ECProperty propertyName="LastName
" typeName="string" displayLabel="Last Name />
<
ECProperty propertyName=
"FullName" typeName=
"string" displayLabel=
"Full Name">
<ECCustomAttributes>
<CalculatedECPropertySpecification xmlns="Bentley_Standard_CustomAttributes.01.00">
<ECExpression>this.LastName & " " & this.FirstName</ECExpression>
<FailureValue> - </FailureValue>
<ParserRegularExpression />
<RequiredSymbolSets />
</ECCustomAttributes>
<
ECProperty propertyName=
"EmployeeID" typeName=
"int" displayLabel=
"Employee ID" />
<
ECProperty propertyName=
"JobTitle" typeName=
"string" displayLabel=
"Job Title" />
<
ECProperty propertyName=
"EmployeeType" typeName=
"int" displayLabel=
"Employee Type">
<ECCustomAttributes>
<StandardValues xmlns="EditorCustomAttributes.01.00">
<MustBeFromList>
False</MustBeFromList>
<ValueMap>
<ValueMap>
<DisplayString>Full Time / Salaried</DisplayString>
</ValueMap>
<ValueMap>
<DisplayString>Part Time</DisplayString>
</ValueMap>
<ValueMap>
<DisplayString>Intern</DisplayString>
</ValueMap>
<ValueMap>
<DisplayString>Full Time / Hourly</DisplayString>
</ValueMap>
</ValueMap>
</StandardValues>
</ECCustomAttributes>
<Employee instanceID= 1" xmlns= Company.02.00 >
<FirstName>Keith</FirstName>
<LastName>Bentley</LastName>
<EmployeeID>0001</EmployeeID>
<JobTitle>Chief Technology Officer</JobTitle>
<EmployeeType>0</EmployeeType>
</Employee>
Again, notice that an instanceID and XML namespace are provided. Since the instance is of a different class, the instanceID does not conflict with the one assigned to the Company instance. Also, since the value for FullName property is calculated, it does not need to be provided. Finally, notice that an integer value is provided for the EmployeeType property and is one of the pre-defined values. Since the value is not constrained to be one of the pre-defined values since the MustBeFromList attribute is set to false, any integer value could have been assigned. However, the integer value would be displayed in the GUI, since it would not have a DisplayString defined for it. The final class and instance to be shown is the EmployeeCompanyrelationship class.
<
ECRelationshipClass typeName=
"EmployeeCompany" isDomainClass=
"True" strength=
"referencing" strengthDirection=
"forward">
<BaseClass>EmployeeRelationshipsBase</BaseClass>
<Source cardinality="(1,N)" roleLabel="Employee working for the Company" polymorphic="True">
<Class class="Employee" />
</Source>
<Target cardinality="(1,1)" roleLabel="Employee of Company" polymorphic="True">
<Class class="Company" />
</Target>
<EmployeeCompany instanceID= 1.1" sourceClass= Employee" sourceInstanceID="1" targetClass= Company" targetInstanceID="1"
xmlns= Company.02.00" />
Notice, relationship instances, like other instances, must have unique instanceIDs assigned to them. Though any string value can be assigned to them, the suggested approach is to concatenated the instanceIDs of the source and target instances. Also, notice that the class names and InstanceIDs of the instances being related are also provided.