1

I want to write an xslt file to transfer an xmi file in a graphical file. But I meet the problem that the edge can not connect the right source node and target node. I have tried already two weeks. But I am still confused. Please help me. Thanks a million.

The original code is:

<?xml version="1.0" encoding="UTF-8"?>
<xml xmlns:xmi="#">
<element xmi:id="BasicElement-Line1" name="Line1" xmi:type="association"/>

<element xmi:id="BasicElement-Line2" name="Line2" xmi:type="association"/>

<element xmi:id="BasicElement-Object1" name="Object1" xmi:type="class">
    <ownedAttribute xmi:type="Property" name="input" type="BasicElement-Object2" association="BasicElement-Line1"/>
    <ownedAttribute xmi:type="Property" name="output" type="BasicElement-Object3" association="BasicElement-Line2"/>
</element>

<element xmi:id="BasicElement-Object2" name="Object2" xmi:type="class">
</element>

<element xmi:id="BasicElement-Object3" name="Object3" xmi:type="class">
</element>
</xml>

and my aim code is:

<?xml version="1.0" encoding="UTF-8"?>
<xmi xmlns:y="##">
   <edge target="N1002D" source="N1001B" id="N10005">
      <y:PolyLineEdge>
         <y:Arrows target="none" source="none" />
      </y:PolyLineEdge>
   </edge>
   <edge target="N1002D" source="N1001B" id="N10010">
      <y:PolyLineEdge>
         <y:Arrows target="none" source="none" />
      </y:PolyLineEdge>
   </edge>
   <node id="N1001B">
      <y:NodeLabel>BasicElement-Object1</y:NodeLabel>
   </node>
   <node id="N1002D">
      <y:NodeLabel>BasicElement-Object2</y:NodeLabel>
   </node>
   <node id="N10033">
      <y:NodeLabel>BasicElement-Object3</y:NodeLabel>
   </node>
</xmi>

Because there will be more "class" element in the future. So I used "{generate-id()}" to define the node IDs. But when I do that, I found the edge can not find the way of source node and target node. So I have already worked on it two weeks and have no idea on it. Please help me, I really appreciate.

Kathi
  • 25
  • 4
  • 1
    I don't find it clear. Your input, and output aren't proper XMLs. Could you post proper input(with a root element and required namespaces), proper output and explanation for how you want to achieve it. – Lingamurthy CS Apr 01 '14 at 19:33
  • 1
    Also, if there is anything in your input that connects Object1 to Object2, please point it out. We had [the same question](http://stackoverflow.com/questions/22611584/transfer-in-graphml) just a few days ago, and the same request for clarification was never answered. – michael.hor257k Apr 01 '14 at 19:40
  • So sorry the original code is like this. I have thought about long time. Maybe the association is the the connection. Like: if element/ownedEnd/@type=element/xmi:id, then source id=xmi:id. if element/[xmi:type="class"]/@type=element/xmi:id, then target id=xmi:id – Kathi Apr 01 '14 at 19:55

1 Answers1

2

I'm not really familiar with XMI and the target format, but here's something that should fit your description.

Source:

<?xml version="1.0" encoding="UTF-8"?>
<xml xmlns:xmi="#">
    <element xmi:id="BasicElement-Line1" name="Line1" xmi:type="association">
         <ownedEnd xmi:type="Property" type="BasicElement-Object1" association="BasicElement-Line1"/>
    </element>

    <element xmi:id="BasicElement-Line2" name="Line2" xmi:type="association">
        <ownedEnd xmi:type="Property" type="BasicElement-Object1" association="BasicElement-Line2"/>
    </element>

    <element xmi:id="BasicElement-Object1" name="Object1" xmi:type="class">
        <ownedAttribute xmi:type="Property" name="input" type="BasicElement-Object2" association="BasicElement-Line1"/>
        <ownedAttribute xmi:type="Property" name="output" type="BasicElement-Object3" association="BasicElement-Line2"/>
    </element>

    <element xmi:id="BasicElement-Object2" name="Object2" xmi:type="class">
    </element>

    <element xmi:id="BasicElement-Object3" name="Object3" xmi:type="class">
    </element>
</xml>

Transformed with (adjust the namespaces to the correct uris):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xmi="#" xmlns:y="##"
exclude-result-prefixes="xmi" version="1.0">
<xsl:output indent="yes"/>

<xsl:template match="xml">
    <xmi>
        <xsl:apply-templates select="element"/>
    </xmi>
</xsl:template>

<xsl:template match="element[@xmi:type='class']">
    <node id="{generate-id()}">
        <y:NodeLabel>
            <xsl:value-of select="@xmi:id"/>
        </y:NodeLabel>
        <y:UMLClassNode/>
    </node>
</xsl:template>

<xsl:template match="element[@xmi:type='association']">
    <!-- association name -->
    <xsl:variable name="association" select="ownedEnd/@association"/>
    <!-- id of source -->
    <xsl:variable name="ownedEnd-type" select="ownedEnd/@type"/>
    <!-- using association variable to select the correct id of target -->
    <xsl:variable name="ownedAttribute-type"
        select="//element[@xmi:id = $ownedEnd-type]/ownedAttribute[@association = $association]/@type"/>
    <edge id="{ generate-id() }" 
        source="{ generate-id( /xml/element[@xmi:id = $ownedEnd-type] ) }"
        target="{ generate-id( /xml/element[@xmi:id = $ownedAttribute-type] ) }">
        <y:PolyLineEdge>
            <y:Arrows source="none" target="none"/>
        </y:PolyLineEdge>
    </edge>
</xsl:template>

</xsl:stylesheet>

gives you:

<xmi xmlns:y="##">
   <edge id="d0e3" source="d0e13" target="d0e20">
      <y:PolyLineEdge>
         <y:Arrows source="none" target="none"/>
      </y:PolyLineEdge>
   </edge>
   <edge id="d0e8" source="d0e13" target="d0e23">
      <y:PolyLineEdge>
         <y:Arrows source="none" target="none"/>
      </y:PolyLineEdge>
   </edge>
   <node id="d0e13">
       <y:NodeLabel>BasicElement-Object1</y:NodeLabel>
       <y:UMLClassNode/>
   </node>
   <node id="d0e20">
       <y:NodeLabel>BasicElement-Object2</y:NodeLabel>
       <y:UMLClassNode/>
   </node>
   <node id="d0e23">
       <y:NodeLabel>BasicElement-Object3</y:NodeLabel>
       <y:UMLClassNode/>
   </node>
</xmi>
Tobias Klevenz
  • 1,625
  • 11
  • 13
  • Hey dear all, the XSLT code can work on my original code now. But I find a problem. When I have more elements(Classes and associations). The association will only connect two nodes. But not for the others. How can I improve this XSLT code? Thanks. – Kathi Apr 03 '14 at 19:53
  • @user3455563 please update your question with an example with multiple associations, and I'll see what I can do. – Tobias Klevenz Apr 03 '14 at 20:02
  • @Kathi please check my update, I used the association to select the correct target id now. I'm pretty sure there could be more issues comming up as you go into more advanced UML Diagrams, did you try an example with a generalization yet? – Tobias Klevenz Apr 03 '14 at 20:43
  • Strange, it is working for me. What's the online Transformer and software you use? – Tobias Klevenz Apr 04 '14 at 07:48
  • Hey Tobi, it works today! I am soooooo happy for that. And I should say thank you many times. Whatever, thanks a million. Have a nice weekend. – Kathi Apr 04 '14 at 20:40
  • Hey Tobi, you are right. Now I meet the problem with generalization. I have tried your way to draw an edge, like to define a variable of general. unfortunately, it doesn't work. Can u help me? Thank u so much. – Kathi Apr 08 '14 at 20:42
  • @Kathi maybe you should open another question for that... I just did a search on github and found https://github.com/ssinan/Xmi2Graphml you can find an Xmi2GrahpMl.xsl in the src dir which actually handles dependencies, so maybe take a look at that first. – Tobias Klevenz Apr 09 '14 at 06:37
  • Thank you Tobi. You are so kind. It it very helpful for me. I will read it and test more. Thanks again. – Kathi Apr 09 '14 at 13:38