I am trying to transform an XML document in SVG using XSLT. I found a
helpful XSL stylesheet written by Wendell Piez a decade ago at
http://www.dpawson.co.uk/xsl/sect4/N10301.html#d14475e189
<http://www.dpawson.co.uk/xsl/sect4/N10301.html#d14475e189> . His XSL
transforms an XSL document into an SVG tree structure. I've used his
stylesheet as a base, but I am struggling trying to figure of how to
calculate the Y axis on each closing tag. I'm hoping that someone might
have some ideas. Am I going about this in the right way?
In reading about similar issues, there is an inherent problem in trying
to determine line count in XML because information can take the form of
an attribute or as the value of an element, thereby altering the line
count (y axis on <text/>. Assuming all XML takes the form of the
following example (house-1.xml), how can I avoid the train wreck in the
resulting SVG when I try to replicate a nested XML document?
In xml2svg-1.xsl, I've added "<!-- Beginning of AREA of FOCUS -->" to
mark where it all goes very wrong for me. Also, I've added resulting
SVG (xml2svg-1.svg) for reference.
Thank you in advance!
Sean
**************
house-1.xml
**************
<?xml version="1.0" encoding="UTF-8"?>
<house>
<bedrooms>
<bedroom type="master">
<bathroom>
<bath type="full"/>
<toilet clean="false"/>
</bathroom>
</bedroom>
<bedroom type="guest">
<bathroom>
<sink type="porcelain"></sink>
<bath type="half"></bath>
<toilet clean="true"></toilet>
</bathroom>
</bedroom>
</bedrooms>
<livingroom >
<tv type="cable" dim="16x9"/>
<furniture>
<couch comfortable="no"/>
<chair comfortable="yes">
<style>arts and crafts</style>
</chair>
</furniture>
</livingroom>
</house>
***************
xml2svg-1.xsl
***************
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<!--
Most of this stylesheet was written by
Wendell Piez, Mulberry Technologies, February 2001.
Revised July 2001.
Found at http://www.dpawson.co.uk/xsl/sect4/N10301.html#d14475e189
-->
<xsl:output method="xml" indent="yes" />
<!-- amend or comment this out if you want to see any
whitespace-only text nodes -->
<xsl:strip-space elements="*"/>
<xsl:param name="across-start" select="6"/>
<!-- a left margin -->
<xsl:param name="down-start" select="4"/>
<!-- a top margin -->
<xsl:param name="across-interval" select="14"/>
<!-- size of each horizontal step -->
<xsl:param name="down-interval" select="18"/>
<!-- size of each vertical step -->
<xsl:param name="writing-bump-over" select="6"/>
<xsl:param name="writing-bump-up" select="-3"/>
<!-- allow for positioning of node labels -->
<!-- internal functions to calculate position for any node -->
<xsl:template name="get-x-coordinate">
<xsl:param name="node" select="/*"/>
<xsl:value-of
select="(count($node/ancestor-or-self::node()) *
$across-interval) + $across-start"/>
</xsl:template>
<xsl:template name="get-y-coordinate">
<xsl:param name="node" select="/*"/>
<xsl:value-of
select="(count($node/preceding::node()|
$node/ancestor-or-self::node()) *
$down-interval) + $down-start"/>
</xsl:template>
<!-- ROOT -->
<xsl:template match="/*">
<svg>
<g>
<!-- -->
<!-- following param only sets starting point for parent node
coordinates - s -->
<xsl:apply-templates select="." mode="label">
<xsl:with-param name="self-x" select="$across-start +
$across-interval"/>
<xsl:with-param name="self-y" select="$down-start +
$down-interval"/>
</xsl:apply-templates>
<xsl:apply-templates/>
</g>
</svg>
</xsl:template>
<xsl:template match="*" mode="label">
<xsl:param name="self-x"/>
<xsl:param name="self-y"/>
<xsl:if test="..">
<!-- element nodes -->
<xsl:text></xsl:text>
</xsl:if>
<text x="{$self-x + $writing-bump-over}" y="{$self-y -
$writing-bump-up}" style="bold; stroke:none; fill:red">
<xsl:if test="not(..)">
<!-- the root node gets labeled with a / -->
<xsl:text></xsl:text>
</xsl:if>
<!-- Element start tag - s -->
<xsl:text><</xsl:text>
<xsl:value-of select="local-name()"/>
<xsl:if test="@*">
<!-- any attribute nodes are written out too -->
<tspan style="bold; stroke:none; fill:blue">
<xsl:for-each select="@*">
<xsl:text> </xsl:text>
<xsl:value-of select="local-name()"/>
<xsl:text>=</xsl:text>
<xsl:text>"</xsl:text>
<xsl:value-of select="."/>
<xsl:text>"</xsl:text>
</xsl:for-each>
</tspan>
</xsl:if>
<xsl:text>></xsl:text>
</text>
<!-- *************************** -->
<!-- Beginning of AREA of FOCUS -->
<!-- ***** Closing Tag ***** -->
<!-- variable vdepth walks branches -->
<!-- *************************** -->
<!-- -->
<xsl:variable name="vdepth">
<xsl:value-of select="count(descendant-or-self::*)"/>
</xsl:variable>
<text x="{$self-x + $writing-bump-over}" y="{($self-y -
$writing-bump-up) + (($vdepth * 2)*$down-interval)}" style="bold;
stroke:none; fill:red">
<xsl:if test="not(..)">
<!-- the root node gets labeled with a / -->
<xsl:text></xsl:text>
</xsl:if>
<xsl:text></</xsl:text>
<xsl:value-of select="local-name()"/>
<xsl:text>></xsl:text>
</text>
<!-- *************************** -->
<!-- END of AREA of FOCUS -->
<!-- *************************** -->
</xsl:template>
<!-- template for any child node -->
<xsl:template match="node()">
<!-- since we're going to draw a line from the parent
to the node, we first need to ask "do you know
where your parents are?" -->
<xsl:variable name="parent-x">
<xsl:call-template name="get-x-coordinate">
<xsl:with-param name="node" select=".."/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="parent-y">
<xsl:call-template name="get-y-coordinate">
<xsl:with-param name="node" select=".."/>
</xsl:call-template>
</xsl:variable>
<!-- then we need to know where we ourselves are at -->
<xsl:variable name="self-x">
<xsl:call-template name="get-x-coordinate">
<xsl:with-param name="node" select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="self-y">
<xsl:call-template name="get-y-coordinate">
<xsl:with-param name="node" select="."/>
</xsl:call-template>
</xsl:variable>
<!-- place a label on the node
(each node type gets a different label) -->
<xsl:apply-templates select="." mode="label">
<xsl:with-param name="self-x" select="$self-x"/>
<xsl:with-param name="self-y" select="$self-y"/>
</xsl:apply-templates>
<!-- descend to the next level down -->
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
*************
xml2svg-1.svg
*************
<?xml version="1.0" encoding="utf-8"?>
â¨<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
â¨<g>â¨
<text x="26" y="25" style="bold; stroke:none;
fill:red"><house></text>â¨
<text x="26" y="637" style="bold; stroke:none;
fill:red"></house></text>â¨
<text x="54" y="61" style="bold; stroke:none;
fill:red"><bedrooms></text>â¨
<text x="54" y="421" style="bold; stroke:none;
fill:red"></bedrooms></text>â¨
<text x="68" y="79" style="bold; stroke:none;
fill:red"><bedroom<tspan style="bold; stroke:none; fill:blue">
type="master"</tspan>></text>â¨
<text x="68" y="223" style="bold; stroke:none;
fill:red"></bedroom></text>â¨
<text x="82" y="97" style="bold; stroke:none;
fill:red"><bathroom></text>â¨
<text x="82" y="205" style="bold; stroke:none;
fill:red"></bathroom></text>â¨
<text x="96" y="115" style="bold; stroke:none; fill:red"><bath<tspan
style="bold; stroke:none; fill:blue">
type="full"</tspan>></text>â¨
<text x="96" y="151" style="bold; stroke:none;
fill:red"></bath></text>â¨
<text x="96" y="133" style="bold; stroke:none;
fill:red"><toilet<tspan style="bold; stroke:none; fill:blue">
clean="false"</tspan>></text>â¨
<text x="96" y="169" style="bold; stroke:none;
fill:red"></toilet></text>â¨
<text x="68" y="151" style="bold; stroke:none;
fill:red"><bedroom<tspan style="bold; stroke:none; fill:blue">
type="guest"</tspan>></text>â¨
<text x="68" y="331" style="bold; stroke:none;
fill:red"></bedroom></text>â¨
<text x="82" y="169" style="bold; stroke:none;
fill:red"><bathroom></text>â¨
<text x="82" y="313" style="bold; stroke:none;
fill:red"></bathroom></text>â¨
<text x="96" y="187" style="bold; stroke:none; fill:red"><sink<tspan
style="bold; stroke:none; fill:blue">
type="porcelain"</tspan>></text>â¨
<text x="96" y="223" style="bold; stroke:none;
fill:red"></sink></text>â¨
<text x="96" y="205" style="bold; stroke:none; fill:red"><bath<tspan
style="bold; stroke:none; fill:blue">
type="half"</tspan>></text>â¨
<text x="96" y="241" style="bold; stroke:none;
fill:red"></bath></text>â¨
<text x="96" y="223" style="bold; stroke:none;
fill:red"><toilet<tspan style="bold; stroke:none; fill:blue">
clean="true"</tspan>></text>â¨
<text x="96" y="259" style="bold; stroke:none;
fill:red"></toilet></text>â¨
<text x="54" y="241" style="bold; stroke:none;
fill:red"><livingroom></text>â¨
<text x="54" y="457" style="bold; stroke:none;
fill:red"></livingroom></text>â¨
<text x="68" y="259" style="bold; stroke:none; fill:red"><tv<tspan
style="bold; stroke:none; fill:blue"> type="cable"
dim="16x9"</tspan>></text>â¨
<text x="68" y="295" style="bold; stroke:none;
fill:red"></tv></text>â¨
<text x="68" y="277" style="bold; stroke:none;
fill:red"><furniture></text>â¨
<text x="68" y="421" style="bold; stroke:none;
fill:red"></furniture></text>â¨
<text x="82" y="295" style="bold; stroke:none; fill:red"><couch<tspan
style="bold; stroke:none; fill:blue">
comfortable="no"</tspan>></text>â¨
<text x="82" y="331" style="bold; stroke:none;
fill:red"></couch></text>â¨
<text x="82" y="313" style="bold; stroke:none; fill:red"><chair<tspan
style="bold; stroke:none; fill:blue">
comfortable="yes"</tspan>></text>â¨
<text x="82" y="385" style="bold; stroke:none;
fill:red"></chair></text>â¨
<text x="96" y="331" style="bold; stroke:none;
fill:red"><style></text>â¨
<text x="96" y="367" style="bold; stroke:none;
fill:red"></style></text>â¨
<!-- unhandled element value -->â¨
<!--⨠<text x="96" y="367" style="bold; stroke:none;
fill:red"></style></text>arts and crafts⨠-->â¨
</g>â¨
</svg>
[Non-text portions of this message have been removed]
------------------------------------
-----
To unsubscribe send a message to: [email protected]
-or-
visit http://groups.yahoo.com/group/svg-developers and click "edit my
membership"
----Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/svg-developers/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/svg-developers/join
(Yahoo! ID required)
<*> To change settings via email:
[email protected]
[email protected]
<*> To unsubscribe from this group, send an email to:
[email protected]
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/