SCXML:状态机批注和语音应用程序开发

开发者在线 Builder.com.cn 更新时间:2006-04-14作者:Peter V. Mikhalenko 来源:

很多其他基于XML的状态机批注已经被开发出来,但是还没有哪一个能够实现与SCXML相同的目的。XMI是一个开发用来表示UML图表的批注,其中包括Harel State Chart。但是它的目的是作为一种机器互换格式,而不能被人编写。

ebXML是一种业务处理规范(用于支持B2B电子商务应用程序)语言。它包括一门状态机语言,这在某种程度上类似本文所讲到的语言,但是它的句法和语义与电子商务密切相关。因此它不适合作为一种通用状态机语言。

XTND的全名是XML转换网络定义(XML Transition Network Definition),它是用于简单有限状态机的批注,但是缺少对多层次和并行状态的Harel的批注,因此不适合做通用状态机,因为它在语义上无法与Harel state chart相对应。

SCXML批注

基础知识

<scxml>前面的XML示例已经表明顶层的根元素是<scxml>。有一个必需的“initialstate”属性。它是文档初始状态的id。状态机会在文档初始化的最后一步转换到这一状态。<scxml>可以有<state><datamodel>元素作为其子元素。

<state>:用来保存状态的表示。其中,它可以有一个“final”属性,以表明这是否是最终状态。最终状态可以没有亚状态和向外转换。<state>元素可以有下列子元素:

  • <onentry>:可选元素,用来保存进入这个<state>时需要运行的可执行内容。
  • <onexit>:可选元素,用来保存退出这个<state>时需要运行的可执行内容。
  • <transition>:用来定义从这个<state>的向外转换(outgoing transition)。
  • <initial>:用来识别具有亚状态的状态机的初始状态的子元素。只有当状态机有一个或者多个<state>子元素时才需要这个子元素。
  • <state>:用来定义父状态的连续亚状态。
  • <parallel>:用来定义一组并行亚状态,这可以发生0次或者1次。它与<state>属性不能并存。
  • <history>:一个用来表示后续状态(也就是系统父状态最后一次转换的父状态所处的状态)的子状态。将这个状态作为目标的转换事实上是到父状态的其他后续状态的转换。
  • <join>:用来同步并行区域的伪状态。
  • <datamodel>:数据模型的可选规范。
  • <invoke>:用来调用外部组件,这可能发生0次或者1次。它与<state><parallel>元素不能同时使用。

这些元素中的大多数我们都已经在上面的示例里看到过。

状态之间的转换由事件来触发,通过警戒条件来条件化。<transition>元素的“target(目标)”可选属性用来指定转换的目标状态,这可能是<state>或是一个<parallel>区域。转换所包含的任何可执行内容都在源状态的<onexit>处理程序之后,在目标状态<onentry>处理程序之前被执行。在转换的“cond”属性和可执行内容里,特殊的变量‘_eventdata’可以被用来访问触发事件里的数据。

<parallel>元素是一个用来封装并行状态机的包装程序。<parallel>元素有类似于<state><onenter><onexit>属性。此外,<parallel>元素保存有一组<state>元素,后者能够并行执行且参与<parallel>元素的<onexit>处理程序。

伪状态

伪状态元素不具备状态的完整属性。但是,它们可以在很多地方像状态一样被使用。尤其是它们常常成为<transition>元素的“目标”。

<initial>元素表示带有连续亚状态的复合状态的默认初始状态。假设<state> S1状态有S11、S12、和S13三个子状态。如果系统处于S1状态,那它必须同时处于S11、S12、S13子状态中的一种,而且只能是一种。<state> S2的<transition>可以将S11、S12或者S13作为其“目标”,但是它还可以简单地指定父状态S1。在本文里,S1的<initial>子状态会指定系统应该转换到S11、S12或者S13中的哪一个状态。你可以在示例3(example3.txt)中看到它是如何运行的。这里嵌入的<transition>元素是一个无条件转换。(也就是说,这个转换不带有<cond><event>属性。)这样一种转换总是处于激活状态,并会在进入状态的时候的进行转换。

<history>伪状态允许‘暂停和恢复(pause and resume)’控制流。每当退出复合<state>时,它的<history>伪状态,如果有的话,会在退出的时候记录状态配置情况。

<join>伪状态提供了障碍逻辑(barrier logic)对于已定义的控件线程进行同步。它的语义已经在示例4(example4.txt)里讨论过。

数据模型

为了给访问本地和远程数据提供统一的方法,能够封装任何数量的<data>元素的<datamodel>标记被引入。每个这样的元素都会定义一个值为XML树的数据元素。XML树可从外部数据源或者指定的内嵌数据源获得。通过<data>标记来访问数据对于SCXML解释器来说是本地的,不能与任何外部数据源进行共享。

构成数据模型的XML树在外来的版本里会如何指定、访问和修改,以及SCXML翻译器的实现仍有待讨论。

<datamodel>元素是数据模型的包装程序。它的子元素<data>可以发生0次或者1次。每个实例都会定义一个叫做XML的数据树。数据树在加载文档的时候被创建。

可执行内容

可执行内容包括进行转换和进入或者离开状态(<onentry><onexit>等)所采取的行动。一般来说,这样的内容必须能够修改数据模型、引发事件、调用底层平台的功能等。另外一方面,可执行内容不一定会引起转换或者任何形式的状态改变,除非是非直接地引发事件,然后被转换捕捉到。可执行模型来自CCXML,这会在下一篇文章里讨论。

<assign>标记可以被用来修改数据模型。相对于可执行内容的特定块为本地的变量可以用<var>元素来公布和初始化,其结果是将可选的<expr>属性作为表达式来计算。

<script>元素含有用ECMAScript写成的计算指令。根据当前的规范,它的实现必须支持ECMAScript Compact Profile,而且可以支持完整的ECMA-262 ECMAScript规范。该规范必须在可执行内容被处理的时候计算其中的<script>

还有其他一些可以用于执行逻辑的元素,比如<if><else><elseif>

事件

事件是SCXML里最基本的概念之一,因为大多数事件都是由它们推动的。事件的名称与转换的<event>属性相同。在很多应用程序里,SCXML接受来自外部实体(例如与<invoke><send>相关联的实体)的事件,这十分重要。在大多数情况下,在SCXML文档执行的过程中所触发的事件集都是应用程序专用的,并通过使用<send>标记来控制和生成。但是,某些特定的事件是必须要有的,并由解释器自动生成。

责任编辑:张琎

查看本文的国际来源

用户评论

  • 用户名
  • 评论内容