对于CIM而言,每个自定义对象都必须与一个EC类相关联,而且,自定义对象的类层次结构必须与所关联EC类的类层次结构相一致;自定义对象通过Schema名称以及EC类名称来全局唯一的引用特定的EC类定义。对于初始接触EC的开发者而言,EC相关的术语可能比较难以理解,下面就EC相关术语做一些类比方式的解释:
1. EC Schema: 它是一个扩展名为.ecschema.xml 的XML文件,其顶层节点的类型名为ECSchema。其中包含任意多个 EC 类的定义,我们可以把它想象成数据库系统的表结构集合,也可以把它想象成用特定语言编写的数据结构定义集合。
2. EC Class: 它是包含在EC Schema中的一个用于定义EC类构成的XML节点,其类型名为ECClass。在其中,我们可以包含任意多个属性的定义。为了便于理解,我们可以把EC Class想象成数据库系统中一个特定的表结构定义,也可以把它想象成用特定语言编写的一个数据结构的定义;与数据库表结构不同的是,EC Class的定义是可以被继承的,也就是允许基于现有的EC Class定义新的EC Class,并在其中增加新的属性定义,这样,新的EC Class中除了包含新增的之外,还包含从基类中继承的属性定义;
3. EC Property: 它是包含在EC Class中的一个名为ECProperty的XML节点,主要用于描述EC Class中一个属性的类型及其相关特性。为了便于理解,我们可以把EC Property想象成数据库系统中一个特定表结构定义中的一个特定的字段的定义,也可以把它想象成用特定语言编写的一个特定数据结构中的一个成员变量;目前,所支持的EC属性类型有: int (32位有符号整数)、long (64位有符号整数)、double (双精度浮点数)、boolean (布尔值)、string (字符串)、binary (二进制数据块)、point2d (2D点)、point3d (3D点);除了支持单值属性外,还支持数组类型的多值属性。
4. EC Instance: 它是特定EC Class的一个实例,用于代表以特定EC Class为模板(或数据组成方式)的运行时数据结构实例,在这个实例中,所基于的EC Class 中的每个EC Property在此实例中都拥有自己的值。为了便于理解,我们可以将它想象成数据库系统中基于特定表结构的一条记录,这个记录由多个字段值组成,每个字段类型都对应于表结构中的特定字段,当然,也可以将它想象成用特定语言所定义数据结构的一个运行时实例;
为了更直观的理解如何定义Schema,接下来我们将对照着一个实际的例子来解释:
<?xml version="1.0" encoding="utf-8"?> <ECSchema schemaName="Bentley_CIM_Tunnel" nameSpacePrefix="bbft" version="1.0" xmlns="http://www.bentley.com/schemas/Bentley.ECXML.2.0"> <ECSchemaReference name="EditorCustomAttributes" version="01.00" prefix="beca" /> <ECSchemaReference name="Bentley_Standard_CustomAttributes" version="01.13" prefix="bsca" /> <ECSchemaReference name="CIMCore" version="01.00" prefix="bbc" /> <ECClass typeName="CIMTunnelGraphicElement" isDomainClass="True"> <BaseClass>bbc:CIMGraphicElement</BaseClass> </ECClass> <ECClass typeName="CIMTunnelLinearElement" isDomainClass="True"> <BaseClass>CIMTunnelGraphicElement</BaseClass> <ECProperty propertyName="Length" typeName="double" displayLabel="Length" /> </ECClass> <ECClass typeName="CIMTunnelPipeElement" isDomainClass="True"> <BaseClass>CIMTunnelLinearElement</BaseClass> <ECProperty propertyName="Radius" typeName="double" displayLabel="Radius" /> <ECProperty propertyName="Diameter" typeName="double" displayLabel="Diameter" /> <ECProperty propertyName="Thickness" typeName="double" displayLabel="Thickness" /> </ECClass> </ECSchema>
上例中定义了一个包含有3个EC类的Schema,这个Schema的名称为Bentley_CIM_Tunnel,命名空间前缀为bbft,当前版本号为1.0
上例Schema中引用到了3个外部的Schema文件,这些引用的定义包含在名为ECSchemaReference的节点中;需要注意的是,所引用Schema的名称、版本号以及前缀名称(prefix属性)必须与对应Schema文件中所
定义的相匹配,而且所引用的Schema的文件名应为:Schema名称(区分大小写) + 版本号 + .ecschema.xml,如:EditorCustomAttributes.01.00.ecschema.xml
每个EC类的定义均包含在名为ECClass的节点中,每个ECClass中可以包含任意多个ECProperty节点和任意多个BaseClass节点,它们代表此EC类中所包含的属性以及此EC类的基类;每个EC类中的 typeName和isDomainClass属性必须提供,它们分别代表此EC类的类型名称以及是否为域类;
每个包含在EC类中的ECProperty节点都代表一个属性或字段,它的名称、类型以及显示名称分别用 propertyName、typeName以及displayLabel属性来表示,而且都是必选的;其中的displayLabel用于属性面板显示属性,typeName可以使用的值在前面已经介绍了;例外的是,如果要在typeName中将特定EC类作为自定义类型来使用,则这个特定EC类定义中除了包含必须isDomainClass="True"外,还需要包含 isStruct="True" 属性;
每个EC类中都可以包含任意多个名为BaseClass的节点,用以表达此类的基类;需要注意的是,如果所指示的基类不包含在当前Schema文件中,则需要使用 Prefix:Name方式来指示,如:bbc:CIMGraphicElement表示CIMCore这个Schema中的CIMGraphicElement 类,因为从ECSchemaReference中可知,bbc是CIMCore的命名空间前缀;另一个需要注意的是,EC类中所包含EC Property的名称(propertyName)在类范围内不允许重复,包括基类在内;
为了确保系统在运行时能找到并加载特定的Schema,需要将定义好的Schema文件放在产品安装后的根目录下的ECSchemas下的特定子目录中;
用户定义Schema中的任何EC类,都必须直接或间接的派生于CIMCore中的类;
最后一个需要特别注意的是,在Schema文件中出现的任何内容都是大小写敏感的,所以一定要确保其正确性;