Hi diayers,
I thought yesterday that DIA needed a better (generic yet customizable)
exporting code for the objects that one designs and fill with info. It came to my mind
that DIA was based on an xml format which has a language for transformation (aka
export): XSLT. So i tried tomorrow to make a stylesheet that exports UML to C++ code
and found that it's really cool and not as time consuming (about 1 hour, but I'm
experienced with XSL) as hacking dia2code.
For the transformation process, you'll need an external XSL processor. I use
xsltproc (a command line transformer based on the C XSLT library for GNOME) and it's
quite powerful. I attached my first stylesheet, so you just need to run :
xsltproc dia-uml2c++.xsl diagram.dia
and you'll see your classes definitions appear.
I think I'm gonna make a package for the different languages if someone find
it useful.
--
"Black holes are where God divided by zero." - Steven Wright
MaT|TaM
<?xml version="1.0"?>
<!--
Transform dia UML objects to C++ classes
Matthieu Sozeau <[EMAIL PROTECTED]>
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dia="http://www.lysator.liu.se/~alla/dia/"
version="1.0">
<xsl:output method="text"/>
<xsl:template match="dia:object[@type='UML - Class']">
<xsl:text>class </xsl:text>
<xsl:value-of select="substring-before(substring-after(dia:attribute[@name='name']/dia:string, '#'), '#')"/>
<xsl:if test="dia:attribute[@name='stereotype']">
<xsl:text> : public </xsl:text>
<xsl:value-of select="substring-before(substring-after(dia:attribute[@name='stereotype']/dia:string, '#'), '#')"/>
</xsl:if>
<xsl:text> {

</xsl:text>
<xsl:apply-templates select="dia:attribute[@name='attributes']"/>
<xsl:text>
</xsl:text>
<xsl:apply-templates select="dia:attribute[@name='operations']"/>
<xsl:text>
};
</xsl:text>
</xsl:template>
<xsl:template match="dia:attribute[@name='attributes']">
<xsl:if test="dia:composite[@type='umlattribute']/dia:attribute[@name='visibility']/dia:enum/@val=2">
<xsl:text> private:
</xsl:text>
<xsl:for-each select="dia:composite[@type='umlattribute']/dia:attribute[@name='visibility']/dia:enum[@val=2]">
<xsl:apply-templates select="../.."/>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:if>
<xsl:if test="dia:composite[@type='umlattribute']/dia:attribute[@name='visibility']/dia:enum/@val=1">
<xsl:text> protected:
</xsl:text>
<xsl:for-each select="dia:composite[@type='umlattribute']/dia:attribute[@name='visibility']/dia:enum[@val=1]">
<xsl:apply-templates select="../.."/>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:if>
<xsl:if test="dia:composite[@type='umlattribute']/dia:attribute[@name='visibility']/dia:enum/@val=0">
<xsl:text> public:
</xsl:text>
<xsl:for-each select="dia:composite[@type='umlattribute']/dia:attribute[@name='visibility']/dia:enum[@val=0]">
<xsl:apply-templates select="../.."/>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="dia:composite[@type='umlattribute']">
<xsl:text> </xsl:text>
<xsl:if test="dia:attribute[@name='class_scope']/dia:boolean/@val='true'">
<xsl:text>static </xsl:text>
</xsl:if>
<xsl:value-of select="substring-before(substring-after(dia:attribute[@name='type']/dia:string, '#'), '#')"/>
<xsl:text> </xsl:text>
<xsl:value-of select="substring-before(substring-after(dia:attribute[@name='name']/dia:string, '#'), '#')"/>
<xsl:text>;
</xsl:text>
</xsl:template>
<xsl:template match="dia:attribute[@name='operations']">
<xsl:if test="dia:composite[@type='umloperation']/dia:attribute[@name='visibility']/dia:enum/@val=2">
<xsl:text> private:
</xsl:text>
<xsl:for-each select="dia:composite[@type='umloperation']/dia:attribute[@name='visibility']/dia:enum[@val=2]">
<xsl:apply-templates select="../.."/>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:if>
<xsl:if test="dia:composite[@type='umloperation']/dia:attribute[@name='visibility']/dia:enum/@val=1">
<xsl:text> protected:
</xsl:text>
<xsl:for-each select="dia:composite[@type='umloperation']/dia:attribute[@name='visibility']/dia:enum[@val=1]">
<xsl:apply-templates select="../.."/>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:if>
<xsl:if test="dia:composite[@type='umloperation']/dia:attribute[@name='visibility']/dia:enum/@val=0">
<xsl:text> public:
</xsl:text>
<xsl:for-each select="dia:composite[@type='umloperation']/dia:attribute[@name='visibility']/dia:enum[@val=0]">
<xsl:apply-templates select="../.."/>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="dia:composite[@type='umloperation']">
<xsl:text> </xsl:text>
<xsl:choose>
<xsl:when test="dia:attribute[@name='visibility']/dia:enum/@val=2">
<xsl:text>virtual </xsl:text>
</xsl:when>
<xsl:when test="dia:attribute[@name='visibility']/dia:enum/@val=3">
<xsl:text>virtual </xsl:text>
</xsl:when>
</xsl:choose>
<xsl:if test="dia:attribute[@name='class_scope']/dia:boolean/@val='true'">
<xsl:text>static </xsl:text>
</xsl:if>
<!-- Constructor has no type -->
<xsl:if test="not(dia:attribute[@name='type']/dia:string='')">
<xsl:value-of select="substring-before(substring-after(dia:attribute[@name='type']/dia:string, '#'), '#')"/>
<xsl:text> </xsl:text>
</xsl:if>
<xsl:value-of select="substring-before(substring-after(dia:attribute[@name='name']/dia:string, '#'), '#')"/>
<xsl:text>(</xsl:text>
<xsl:for-each select="dia:attribute[@name='parameters']/dia:composite[@type='umlparameter']">
<xsl:choose>
<xsl:when test="dia:attribute[@name='kind']/dia:enum/@val=1">
<xsl:text>const </xsl:text>
</xsl:when>
</xsl:choose>
<xsl:value-of select="substring-before(substring-after(dia:attribute[@name='type']/dia:string, '#'), '#')"/>
<xsl:choose>
<xsl:when test="not(dia:attribute[@name='kind']/dia:enum/@val=0)">
<xsl:text>&</xsl:text>
</xsl:when>
</xsl:choose>
<xsl:text> </xsl:text>
<xsl:value-of select="substring-before(substring-after(dia:attribute[@name='name']/dia:string, '#'), '#')"/>
<xsl:if test="not(dia:attribute[@name='value']/dia:string='')">
<xsl:text> = </xsl:text>
<xsl:value-of select="substring-before(substring-after(dia:attribute[@name='value']/dia:string, '#'), '#')"/>
</xsl:if>
<xsl:if test="not(position()=last())">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>)</xsl:text>
<xsl:if test="dia:attribute[@name='visibility']/dia:enum/@val=3">
<xsl:text> = 0</xsl:text>
</xsl:if>
<xsl:if test="dia:attribute[@name='query']/dia:boolean/@val='true'">
<xsl:text> const</xsl:text>
</xsl:if>
<xsl:text>;
</xsl:text>
</xsl:template>
<xsl:template match="text()">
</xsl:template>
<xsl:template match="node()|@*">
<xsl:apply-templates match="node()|@*"/>
</xsl:template>
</xsl:stylesheet>