-2

我有一个关于使用 XSLT 将我的数据模型 (XMI) 转换为 XML 表示的问题。XMI 看起来像这样(片段):

<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="windows-1252"?>
<xmi:XMI xmi:version="2.1" xmlns:uml="http://schema.omg.org/spec/UML/2.1" xmlns:xmi="http://schema.omg.org/spec/XMI/2.1" xmlns:thecustomprofile="http://www.sparxsystems.com/profiles/thecustomprofile/1.0" xmlns:EAUML="http://www.sparxsystems.com/profiles/EAUML/1.0">
<xmi:Documentation exporter="Enterprise Architect" exporterVersion="6.5"/>
<uml:Model xmi:type="uml:Model" name="EA_Model" visibility="public">
    <packagedElement xmi:type="uml:Package" xmi:id="EAPK_F3388CFE_57A7_4d84_8866_3FB3AADE565A" name="Data Model - SQLServer2012" visibility="public">
        <packagedElement xmi:type="uml:Artifact" xmi:id="EAID_B62341D4_41C6_4c83_A60A_4CA65C2E185E" name="«Database» SQLServer2012" visibility="public"/>
        <packagedElement xmi:type="uml:Package" xmi:id="EAPK_BA7676C5_40BC_4bd9_A0F5_F6B15E534E8E" name="Logical Model" visibility="public">
            <packagedElement xmi:type="uml:Class" xmi:id="EAID_2DC36189_CCFB_40bf_A1CB_CD4FB08FE8B5" name="TABLENAME" visibility="public">
                <ownedAttribute xmi:type="uml:Property" xmi:id="EAID_9BBF5184_37F8_4729_9DC1_7ED3B4D8FC98" name="ATTRIBUTE_1" visibility="public" isStatic="false" isReadOnly="false" isDerived="false" isOrdered="true" isUnique="false" isDerivedUnion="false">
                    <lowerValue xmi:type="uml:LiteralInteger" xmi:id="EAID_LI000001_37F8_4729_9DC1_7ED3B4D8FC98" value="1"/>
                    <upperValue xmi:type="uml:LiteralInteger" xmi:id="EAID_LI000002_37F8_4729_9DC1_7ED3B4D8FC98" value="1"/>
                    <type xmi:idref="EASQL_Server_2012_nvarchar"/>
                </ownedAttribute>
                <ownedAttribute xmi:type="uml:Property" xmi:id="EAID_BC1F93D0_A7F4_474c_A27E_26D3ABCCFB7B" name="ATTRIBUTE_2" visibility="public" isStatic="false" isReadOnly="false" isDerived="false" isOrdered="false" isUnique="true" isDerivedUnion="false">
                    <lowerValue xmi:type="uml:LiteralInteger" xmi:id="EAID_LI000003_A7F4_474c_A27E_26D3ABCCFB7B" value="1"/>
                    <upperValue xmi:type="uml:LiteralInteger" xmi:id="EAID_LI000004_A7F4_474c_A27E_26D3ABCCFB7B" value="1"/>
                    <type xmi:idref="EASQL_Server_2012_nvarchar"/>
                </ownedAttribute>

所以现在我想编写一个 XSL 文件,它使我能够提取表名:

-> packagedElement xmi:type="uml:Class"

和属性

-> ownedAttribute xmi:type="uml:Property"

以及每个属性的数据类型。

最后,我需要将这些信息转换成这样的 XML 表示:

<Segment Name="TABLENAME">
  <Elements>
    <Element Name="ATTRIBUTE_1" Type="System.blabla">
    </Element>
    <Element Name="ATTRIBUTE_2" Type="System.blabla">
    </Element>
  </Elements>
</Segment>

有人可以给我一些关于如何实现这一目标的提示/示例吗?

非常感谢任何帮助。

干杯桑德罗

4

2 回答 2

1

这只是一个猜测,因为示例不完整。
这是通过在 TEXT 中指定所有内容来解决的(有点困难),但它对我有用。

  <?xml version="1.0" encoding="UTF-8"?>
  <!-- ================================================== -->
  <xsl:stylesheet  version="2.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:xs="http://www.w3.org/2001/XMLSchema"
     xmlns:uml="http://schema.omg.org/spec/UML/2.1" 
     xmlns:xmi="http://schema.omg.org/spec/XMI/2.1" 
     xmlns:thecustomprofile="http://www.sparxsystems.com/profiles/thecustomprofile/1.0" 
     >
     <xsl:strip-space elements="*"/>
     <xsl:output indent="yes" method="text"/>

     <xsl:template match="xmi:XMI">

        <xsl:for-each select="uml:Model/packagedElement/packagedElement/packagedElement[@xmi:type='uml:Class']">
           <xsl:value-of select="'&lt;Segment Name=&quot;'"/>
           <xsl:value-of select="@name"/>
           <xsl:value-of select="'&quot;&gt;'"/>
           <xsl:value-of select="'&#10;'"/>

           <xsl:value-of select="'&lt;Elements&gt;'"/>
           <xsl:value-of select="'&#10;'"/>

           <xsl:for-each select="ownedAttribute[@xmi:type='uml:Property']">
              <xsl:value-of select="'&lt;Element Name=&quot;'"/>
              <xsl:value-of select="@name"/>
              <xsl:value-of select="'&quot;&gt;'"/>
              <xsl:value-of select="'&#10;'"/>

              <xsl:value-of select="'&lt;/Element&gt;'"/>
              <xsl:value-of select="'&#10;'"/>
           </xsl:for-each>
        </xsl:for-each>

        <xsl:value-of select="'&lt;/Elements&gt;'"/>
        <xsl:value-of select="'&#10;'"/>

        <xsl:value-of select="'&lt;/Segment&gt;'"/>
        <xsl:value-of select="'&#10;'"/>

     </xsl:template>
  </xsl:stylesheet>
于 2015-09-01T13:44:25.657 回答
1

由于您只对 XML 中的几个元素真正感兴趣,因此您可以利用 XSLT 的内置模板,它有效地跳过所有元素并仅输出文本节点(其中 XML 中只有空白节点)。这意味着您只需要编写两个模板;一个用于您确实要处理的每个元素。

因此,对于packagedElement类型为 的uml:Class,您正在创建一个Segment元素,因此模板看起来像这样

<xsl:template match="packagedElement[@xmi:type='uml:Class']">
    <Segment Name="{@name}">
        <Elements>
            <xsl:apply-templates />
        </Elements>
    </Segment>            
</xsl:template>

请注意在创建属性时使用属性值模板Name。花括号意味着必须评估表达式,而不是按字面输出。

对于ownedAttribute元素也是如此。

<xsl:template match="ownedAttribute[@xmi:type='uml:Property']">
    <Element Name="{@name}" Type="System.blabla">
    </Element>         
</xsl:template>

试试这个 XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
                xmlns:xmi="http://schema.omg.org/spec/XMI/2.1">
    <xsl:output method="xml" indent="yes" />
    <xsl:strip-space elements="*" />

    <xsl:template match="packagedElement[@xmi:type='uml:Class']">
        <Segment Name="{@name}">
            <Elements>
                <xsl:apply-templates />
            </Elements>
        </Segment>            
    </xsl:template>

    <xsl:template match="ownedAttribute[@xmi:type='uml:Property']">
        <Element Name="{@name}" Type="System.blabla">
        </Element>         
    </xsl:template>
</xsl:stylesheet>

还要注意命名空间前缀是如何定义的,命名xmi空间 URI 与输入 XML 中的 URI 匹配。

于 2015-09-01T16:42:17.090 回答