Search code examples
xmlxsltsvgconvertersgraph-visualization

How to transform custom graphic format to SVG graphics view via XSLT?


I have custom graphic format in xml-like format. I want to arrange nodes, textview and edges as is, definitely. My approach is to use XSL transformations from xml to svg. I'm new to svg format but worked a little with xsl previosuly. I wonder if such a task already solved like graphml to svg feature in yEd. Is there some handy method to make such a transformation?

<?xml version="1.0" encoding="windows-1251"?>
<project version="1.2">
  <calc allowworktime="false" cutoff="0"/>
  <sfc>
    <graphview>
      <nodeview idref="1">
        <properties>
          <color value="#FF000000" name="outline.color"/>
          <rectangle left="165" top="85" right="195" bottom="115" name="bounds"/>
          <color value="#FFFFFFFF" name="fill.color"/>
        </properties>
      </nodeview>
      <edgeview idref="1">
        <properties>
          <color value="#FF000000" name="outline.color"/>
        </properties>
      </edgeview>
      <textview>
        <properties>
          <color value="#00000000" name="outline.color"/>
          <color value="#FF000000" name="label.font.color"/>
          <integer value="8" name="label.font.size"/>
          <rectangle left="176" top="63" right="194" bottom="78" name="bounds"/>
          <string value="Tahoma" name="label.font.family"/>
          <color value="#00000000" name="fill.color"/>
          <integer value="0" name="label.font.style"/>
          <string value="Ë1" name="label.text"/>
        </properties>
      </textview>
    </graphview>
  </sfc>
</project>

I've just created sample xslt that can transform nodeviews to rects, but svg not rendered somehow when opened in inkscape.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:local="local"
    exclude-result-prefixes="xs"
    version="2.0"
    xmlns:svg="http://www.w3.org/2000/svg">
    <xsl:output indent="yes"/>

    <xsl:template match="/">
        <svg>
        <xsl:apply-templates select="@* | node()"/>
                </svg>

            </xsl:template>

    <xsl:template match="//graphview/nodeview">
        <xsl:variable name="nodeleft" select="properties/rectangle/@left"/>
        <xsl:variable name="noderight" select="properties/rectangle/@right"/>
        <xsl:variable name="nodetop" select="properties/rectangle/@top"/>
        <xsl:variable name="nodebottom" select="properties/rectangle/@bottom"/>
        <!-- adding svg group item -->
        <g>
            <xsl:element name="rect">
                <xsl:attribute name="x"><xsl:value-of select="$nodeleft"/></xsl:attribute>
                <xsl:attribute name="width"><xsl:value-of select="($noderight - $nodeleft)"/></xsl:attribute>
                <xsl:attribute name="height"><xsl:value-of select="($nodetop - $nodebottom)"/></xsl:attribute>
                <xsl:attribute name="y"><xsl:value-of select="($nodetop)"/></xsl:attribute>
            </xsl:element>
        </g>
    </xsl:template>
</xsl:stylesheet>

Solution

  • The main problem with your stylesheet is that the elements you are creating are not in the SVG namespace. You can fix that easily by making the SVG namespace the default namespace of the stylesheet - IOW, change this:

    xmlns:svg="http://www.w3.org/2000/svg"
    

    to:

    xmlns="http://www.w3.org/2000/svg"
    

    The other thing is that your calculation returns a negative height, which is not allowed in SVG.