您的位置:首页 > 其它

[1.2]由UML模型通过XMI生成XML,通过XSLT展示到表现层

2005-03-28 14:30 351 查看
本专栏当前的话题是建模、UML 和 XML。具体而言,即研究 UML 建模在 XML 开发中的应用,特别是如何用 XSLT 样式表实现自动派生。

随着 XML 成为开发项目的一种常见特性,很多开发人员对把 XML 和开发过程中的其他部分结合起来越来越感兴趣。尽管许多组织仍然依靠专门的工具进行 XML 开发,但大的趋势是在 XML 的开发中采用其他开发需求已经使用的方法论,或者至少是一组通用的工具,比如 Java 技术、数据库和 Web。

自动派生

上一期已经指出,模型是帮助计算和预测的系统简化描述。在本文的环境中,所谓系统指的都是 XML 词汇表。

图 1 表示的是模型连续体(continuum)的建模过程。第一个模型是画在白板(或者一沓纸)上的,一般不那么正规。这个阶段的目标是让所有的参与者(用户、开发人员和设计人员)有机会自由地表达自己的观点。

图 1. 模型连续体

<?xml version="1.0"?>

<XMI xmi.version="1.2" xmlns:UML="org.omg/UML/1.4">

 <XMI.header>

  <XMI.documentation>

   <XMI.exporter>ananas.org stylesheet</XMI.exporter>

  </XMI.documentation>

  <XMI.metamodel xmi.name="UML" xmi.version="1.4"/>

 </XMI.header>

 <XMI.content>

  <UML:Model xmi.id="M.1" name="address" visibility="public"

              isSpecification="false" isRoot="false"

              isLeaf="false" isAbstract="false">

   <UML:Namespace.ownedElement>

    <UML:Class xmi.id="C.1" name="address" visibility="public"

               isSpecification="false" namespace="M.1" isRoot="true"

               isLeaf="true" isAbstract="false" isActive="false">

     <UML:Classifier.feature>

      <UML:Attribute xmi.id="A.1" name="name" visibility="private"

                     isSpecification="false" ownerScope="instance"/>

      <UML:Attribute xmi.id="A.2" name="street" visibility="private"

                     isSpecification="false" ownerScope="instance"/>

      <UML:Attribute xmi.id="A.3" name="zip" visibility="private"

                     isSpecification="false" ownerScope="instance"/>

      <UML:Attribute xmi.id="A.4" name="region" visibility="private"

                     isSpecification="false" ownerScope="instance"/>

      <UML:Attribute xmi.id="A.5" name="city" visibility="private"

                     isSpecification="false" ownerScope="instance"/>

      <UML:Attribute xmi.id="A.6" name="country" visibility="private"

                     isSpecification="false" ownerScope="instance"/>

     </UML:Classifier.feature>

    </UML:Class>

   </UML:Namespace.ownedElement>

  </UML:Model>

 </XMI.content>

</XMI>

要注意,清单 1 中的 XML 元素和属性是如何与 图 2 中的类和属性匹配的。您现在又回到了原地:XMI 文档是 UML 元模型的直接表示,因为 UML 元模型是 UML 本身的描述。

表示的问题

UML 元模型的一部分处理概念的可视化表示——把概念画到屏幕的何处。由于两方面的原因我的样式表中没有处理这些信息:

从 UML 模型派生出 XML 模式不需要这些信息。

从 XML 模式派生 UML 模型时生成可视化的输出非常困难。更合理的选择是用建模工具打开模型,花几分钟准备模型在屏幕上的可视化表示。最困难的工作(正确的定义)已经由样式表完成了。

XSLT 样式表

现在您已经掌握了阅读 XMI 文件的要点,很容易就能把 XMI 标签映射成等价的 XML 模式。一种可能的映射是:

UML:Model
变成
xs:schema
;目标名称空间从模型名导出。

UML:Class
变成全局 XML 元素声明(
xs:element
)。

UML:Attribute
变成本地 XML 元素声明(
xs:element
)。

清单 2 是实现这种映射的 XSLT 样式表:

清单 2. XML 模式派生

<?xml version="1.0"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

                xmlns:xs="http://www.w3.org/2001/XMLSchema"

                xmlns:UML="org.omg/UML/1.4"

                exclude-result-prefixes="UML"

                version="1.0">

<xsl:output indent="yes"/>

<xsl:template match="XMI[@xmi.version='1.2']">

   <xsl:apply-templates select="XMI.content/UML:Model"/>

</xsl:template>

<xsl:template match="XMI">

   <xsl:message terminate="yes">Unknown XMI version</xsl:message>

</xsl:template>

<xsl:template match="UML:Model">

   <xs:schema targetNamespace="http://psol.com/uml/{@name}">

      <xsl:apply-templates/>

   </xs:schema>

</xsl:template>

<xsl:template match="UML:Namespace.ownedElement/UML:Class">

   <xs:element name="{@name}">

      <xs:complexType>

         <xs:sequence>

            <xsl:apply-templates/>

         </xs:sequence>

      </xs:complexType>

   </xs:element>

</xsl:template>

<xsl:template match="UML:Attribute">

   <xs:element name="{@name}" type="xs:string"/>

</xsl:template>

<xsl:template match="text()">

   <xsl:value-of select="normalize-space(.)"/>

</xsl:template>

</xsl:stylesheet>

显然,清单 2 中的样式表功能非常有限(只进行了很少的错误检查),因为它仅仅支持 UML 元模型很小的一个子集。它没有考虑包、接口、关联等等。只需要对上面描述的过程稍加扩展,就可以进一步完善这个样式表以支持上述概念:研究 UML 元模型中相应的部分、定义到 XML 模式的映射然后实现它。

反过来一样

如果遵循常规的建模流程,很容易得到 清单 2。您经常会发现已经存在一个 XML 模式,可以作为工作的起点。重新建立 UML 模型太麻烦了,如果由一个样式表实现逆映射会非常方便。清单 3 是一个例子:

清单 3. 逆派生(从 XML 模式到 UML)

<?xml version="1.0"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

                xmlns:xs="http://www.w3.org/2001/XMLSchema"

                xmlns:UML="org.omg/UML/1.4"

                exclude-result-prefixes="xs"

                version="1.0">

<xsl:output indent="yes"/>

<xsl:template match="xs:schema">

 <XMI xmi.version="1.2">

  <XMI.header>

   <XMI.documentation>

    <XMI.exporter>dW simple stylesheet</XMI.exporter>

   </XMI.documentation>

   <XMI.metamodel xmi.name="UML" xmi.version="1.4"/>

  </XMI.header>

  <XMI.content>

   <UML:Model xmi.id="{generate-id()}" 

     name="{substring-after(@targetNamespace,'http://psol.com/uml/')}"

     visibility="public" isSpecification="false"

     isRoot="false" isLeaf="false" isAbstract="false">

     <UML:Namespace.ownedElement>

       <xsl:apply-templates/>

     </UML:Namespace.ownedElement>

   </UML:Model>

  </XMI.content>

 </XMI>

</xsl:template>

<xsl:template match="xs:element">

 <UML:Class xmi.id="{generate-id()}" name="{@name}"

    visibility="public" isSpecification="false" isRoot="true"

    isLeaf="true" isAbstract="false" isActive="false">

    <xsl:apply-templates/>

 </UML:Class>

</xsl:template>

<xsl:template match="xs:sequence">

 <UML:Classifier.feature>

  <xsl:apply-templates/>

 </UML:Classifier.feature>

</xsl:template>

<xsl:template match="xs:sequence/xs:element">

 <UML:Attribute xmi.id="{generate-id(.)}" name="{@name}"

                visibility="private" isSpecification="false"

                ownerScope="instance"/>

</xsl:template>

</xsl:stylesheet>

更复杂的样式表

如果要说本文中介绍的样式表很简单,就太过谨慎了。这些例子一般不到 50 行,只能处理 UML 元模型的一个子集。实际的样式表能够识别多得多的 UML 概念,通常需要 500 行甚至更多。本期文章的目标是介绍自动化模型派生背后的概念:

这些模型(UML、XML 模式)都用一个数据集表示,这种特殊的数据集称为元模型。

可以建立 UML 元模型和 XML 模式之间的映射。

可以通过 XSLT 样式表实现这种映射。

UML 和 XML 模式仅仅是同一事实的不同表示,区别在于服务于不同的目标。

如果您尝试扩展 清单 2清单 3 中的样式表,可能会遇到两个问题:

UML 模型可能不够具体(因为是一种高级视图),无法派生出有意义的 XML 模式(低级的、详细的模型)。

UML 元模型和 XML 模式之间可能存在多种合理的映射。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: