You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
345 lines
12 KiB
345 lines
12 KiB
<?xml version='1.0'?>
|
|
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
|
version="1.0"
|
|
xmlns:web="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
xmlns:util="http://www.w3.org/2000/01/rdf-schema#"
|
|
xmlns:g="http://www.w3.org/2001/02pd/gv#"
|
|
>
|
|
|
|
<xsl:variable name="RCSId"
|
|
select='"$Id: rdf2dot.xsl,v 1.19 2005/11/12 00:18:34 connolly Exp $"'/>
|
|
|
|
<xsl:param name="Debug" select='0'/>
|
|
|
|
<div xmlns="http://www.w3.org/1999/xhtml">
|
|
<pre>
|
|
This transformation groks a limited subset of RDF:
|
|
-- just one level of nesting (no Description/typedNodes
|
|
as values of properties)
|
|
-- properties are sorted by subject, collected
|
|
in a Description element for that subject
|
|
-- rdf:ID is not used; only rdf:about
|
|
-- only absolute URIs are used
|
|
|
|
Arbitrary RDF can be converted to this form using
|
|
cwm --rdf foo.rdf --bySubject --base=bogus: > foo-limited.rdf
|
|
|
|
see <a href="http://www.w3.org/2000/10/swap/">Semantic Web Area for Play</a>
|
|
for details about cwm.
|
|
</pre>
|
|
|
|
<address>Dan Connolly <br class=""/>
|
|
$Id: rdf2dot.xsl,v 1.19 2005/11/12 00:18:34 connolly Exp $</address>
|
|
|
|
<p>Norman Walsh updated this stylesheet on 16 Jan 2002 so that edges
|
|
between nodes in different clusters are generated outside of any
|
|
cluster. This prevents nodes from automatically inheriting cluster
|
|
semantics. I also switched to keys() as a comment suggested.</p>
|
|
|
|
</div>
|
|
|
|
<xsl:output method="text"/>
|
|
|
|
<xsl:param name="GVns" select='"http://www.w3.org/2001/02pd/gv#"'/>
|
|
|
|
<xsl:key name="about" match="*" use="@web:about"/>
|
|
|
|
<xsl:template match="/web:RDF">
|
|
<xsl:text>/* transformed by by </xsl:text>
|
|
<xsl:value-of select='substring($RCSId, 2, string-length($RCSId)-2)'/>
|
|
<xsl:text> */
</xsl:text>
|
|
|
|
<xsl:for-each select="*/g:digraph/@web:resource">
|
|
<xsl:variable name="it" select="key('about', current())"/>
|
|
|
|
<xsl:text>digraph </xsl:text>
|
|
<xsl:call-template name="eachGraph">
|
|
<xsl:with-param name="it" select='$it'/>
|
|
<xsl:with-param name="first" select="1"/>
|
|
</xsl:call-template>
|
|
</xsl:for-each>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="eachGraph">
|
|
<xsl:param name="it"/>
|
|
<xsl:param name="cluster"/>
|
|
<xsl:param name="crossGraphLinking" select="0"/>
|
|
<xsl:param name="first" select="0"/>
|
|
|
|
<xsl:if test="$crossGraphLinking = 0">
|
|
<xsl:value-of select='concat($cluster, generate-id($it))'/>
|
|
<xsl:text> {
</xsl:text>
|
|
|
|
<!-- graph attributes see Graphviz spec table 3 -->
|
|
<xsl:for-each select='$it/g:center
|
|
|$it/g:clusterrank
|
|
|$it/g:color
|
|
|$it/g:compound
|
|
|$it/g:concentrate
|
|
|$it/g:fontcolor
|
|
|$it/g:fontname
|
|
|$it/g:fontsize
|
|
|$it/g:label
|
|
|$it/g:layerseq
|
|
|$it/g:margin
|
|
|$it/g:mclimit
|
|
|$it/g:nodesep
|
|
|$it/g:nslimit
|
|
|$it/g:ordering
|
|
|$it/g:orientation
|
|
|$it/g:page
|
|
|$it/g:rank
|
|
|$it/g:rankdir
|
|
|$it/g:ranksep
|
|
|$it/g:ratio
|
|
|$it/g:size
|
|
|$it/g:style
|
|
'>
|
|
<!--@@ ...others-->
|
|
<xsl:value-of select='local-name()'/>
|
|
<xsl:text>="</xsl:text>
|
|
<xsl:value-of select='.'/> <!-- @@quoting? -->
|
|
<xsl:text>";
</xsl:text>
|
|
</xsl:for-each>
|
|
<xsl:if test="$first != 0">
|
|
<xsl:call-template name="eachGraph">
|
|
<xsl:with-param name="it" select='$it'/>
|
|
<xsl:with-param name="crossGraphLinking" select="1"/>
|
|
</xsl:call-template>
|
|
</xsl:if>
|
|
</xsl:if>
|
|
|
|
<!-- explicit nodes -->
|
|
<xsl:for-each select="$it/g:hasNode/@web:resource">
|
|
<xsl:variable name="nodeURI" select='current()'/>
|
|
<xsl:variable name="nodeElt" select='key("about", $nodeURI)'/>
|
|
<xsl:if test='$nodeElt'>
|
|
<xsl:call-template name="eachNode">
|
|
<xsl:with-param name="graphElt" select='$it'/>
|
|
<xsl:with-param name="nodeElt" select='$nodeElt'/>
|
|
<xsl:with-param name="nodeURI" select='$nodeURI'/>
|
|
<xsl:with-param name="crossGraphLinking" select="$crossGraphLinking"/>
|
|
</xsl:call-template>
|
|
</xsl:if>
|
|
</xsl:for-each>
|
|
|
|
<xsl:for-each select="$it/g:subgraph/@web:resource">
|
|
<xsl:variable name="it2" select="key('about', current())"/>
|
|
<xsl:if test="$crossGraphLinking = 0">
|
|
<xsl:text>subgraph </xsl:text>
|
|
</xsl:if>
|
|
|
|
<xsl:call-template name="eachGraph">
|
|
<xsl:with-param name="it" select='$it2'/>
|
|
<xsl:with-param name="cluster" select='"cluster"'/>
|
|
<xsl:with-param name="crossGraphLinking" select="$crossGraphLinking"/>
|
|
</xsl:call-template>
|
|
</xsl:for-each>
|
|
|
|
<xsl:if test="$crossGraphLinking = 0">
|
|
<xsl:text>}
</xsl:text>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="eachNode">
|
|
<xsl:param name="graphElt"/>
|
|
<xsl:param name="nodeElt"/>
|
|
<xsl:param name="nodeURI"/>
|
|
<xsl:param name="crossGraphLinking" select="0"/>
|
|
|
|
<xsl:if test="$crossGraphLinking = 0">
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select='$nodeURI'/>
|
|
<xsl:text>" [</xsl:text>
|
|
|
|
<!-- node attributes -->
|
|
<xsl:for-each select='$nodeElt/g:label
|
|
|$nodeElt/g:color
|
|
|$nodeElt/g:shape
|
|
|$nodeElt/g:style
|
|
|$nodeElt/g:fontcolor
|
|
|$nodeElt/g:fontname
|
|
|$nodeElt/g:fontsize
|
|
|$nodeElt/g:height
|
|
|$nodeElt/g:width
|
|
|$nodeElt/g:layer
|
|
|$nodeElt/g:URL
|
|
|$nodeElt/g:sides
|
|
|$nodeElt/g:shapefile'>
|
|
<!-- "URL" not in the original file format docs, but seems to be supported; -->
|
|
<!-- cf http://www.graphviz.org/webdot/tut2.html -->
|
|
<xsl:value-of select='local-name()'/>
|
|
<xsl:text>="</xsl:text>
|
|
<xsl:value-of select='.'/> <!-- @@quoting? -->
|
|
<xsl:text>",
</xsl:text>
|
|
</xsl:for-each>
|
|
<xsl:text>];
</xsl:text>
|
|
</xsl:if>
|
|
|
|
<!-- edges -->
|
|
<xsl:for-each select="$nodeElt/*[@web:resource]"> <!-- iterate over all properties -->
|
|
<!-- compute full name of property -->
|
|
<xsl:variable name="obj" select='./@web:resource'/>
|
|
<xsl:variable name="pred" select='concat(namespace-uri(), local-name())'/>
|
|
|
|
<xsl:if test='$Debug>4'>
|
|
<xsl:message>propertyElt in nodeElt:
|
|
subj: <xsl:value-of select='$nodeURI'/>
|
|
pred: <xsl:value-of select='$pred'/>
|
|
</xsl:message>
|
|
</xsl:if>
|
|
|
|
<xsl:choose>
|
|
<xsl:when test='$graphElt/g:hasEdgeProperty/@web:resource=$pred
|
|
and $graphElt/g:hasNode/@web:resource=$obj'>
|
|
<xsl:call-template name="doEdge">
|
|
<xsl:with-param name="nodeURI" select='$nodeURI'/>
|
|
<xsl:with-param name="pred" select='$pred'/>
|
|
<xsl:with-param name="obj" select='$obj'/>
|
|
<xsl:with-param name="edgeElt" select='key("about", $pred)'/>
|
|
<xsl:with-param name="crossGraphLinking" select="$crossGraphLinking"/>
|
|
</xsl:call-template>
|
|
</xsl:when>
|
|
|
|
<xsl:when test='/web:RDF/g:EdgeProperty[@web:about=$pred]'>
|
|
<xsl:if test="0">
|
|
<xsl:message>
|
|
<xsl:value-of select='$pred'/> is an EdgeProperty.
|
|
A given property might be used to make edges
|
|
in one graph and not in another; so
|
|
EdgeProperty(p) isn't well-defined those p's.
|
|
It seems that edge-ness is a function of the
|
|
graph and the property; i.e. a relation between
|
|
them.
|
|
|
|
So EdgeProperty is deprecated... use hasEdgeProperty.
|
|
|
|
@@oops... what about g:style, g:label, etc... should
|
|
those be a function of the property and the graph?
|
|
Or should we have edgeLabel and nodeLabel properties?
|
|
Hmm...
|
|
</xsl:message>
|
|
</xsl:if>
|
|
|
|
<xsl:call-template name="doEdge">
|
|
<xsl:with-param name="nodeURI" select='$nodeURI'/>
|
|
<xsl:with-param name="pred" select='$pred'/>
|
|
<xsl:with-param name="obj" select='$obj'/>
|
|
<xsl:with-param name="edgeElt" select='key("about", $pred)'/>
|
|
<xsl:with-param name="crossGraphLinking" select="$crossGraphLinking"/>
|
|
</xsl:call-template>
|
|
</xsl:when>
|
|
|
|
<xsl:when test='/web:RDF/*[@web:about=$pred]/web:type
|
|
[@web:resource=concat($GVns, "EdgeProperty")]'>
|
|
<xsl:if test="0">
|
|
<xsl:message>
|
|
<xsl:value-of select='$pred'/> is an EdgeProperty.
|
|
|
|
A given property might be used to make edges
|
|
in one graph and not in another; so
|
|
EdgeProperty(p) isn't well-defined those p's.
|
|
It seems that edge-ness is a function of the
|
|
graph and the property; i.e. a relation between
|
|
them.
|
|
|
|
So EdgeProperty is deprecated... use hasEdgeProperty
|
|
|
|
@@oops... what about g:style, g:label, etc... should
|
|
those be a function of the property and the graph?
|
|
Or should we have edgeLabel and nodeLabel properties?
|
|
Hmm... maybe
|
|
my:graph g:nodeType my:Marbles;
|
|
g:edgeType my:GEdgeProp;
|
|
g:labelProp my:label;
|
|
g:styleProp my:styleProp;
|
|
</xsl:message>
|
|
</xsl:if>
|
|
|
|
<xsl:call-template name="doEdge">
|
|
<xsl:with-param name="nodeURI" select='$nodeURI'/>
|
|
<xsl:with-param name="pred" select='$pred'/>
|
|
<xsl:with-param name="obj" select='$obj'/>
|
|
<xsl:with-param name="edgeElt" select='key("about", $pred)'/>
|
|
<xsl:with-param name="crossGraphLinking" select="$crossGraphLinking"/>
|
|
</xsl:call-template>
|
|
|
|
</xsl:when>
|
|
|
|
<xsl:otherwise>
|
|
<!-- nothing -->
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
|
|
</xsl:for-each>
|
|
|
|
</xsl:template>
|
|
|
|
<xsl:template name="doEdge">
|
|
<xsl:param name="nodeURI"/>
|
|
<xsl:param name="pred"/>
|
|
<xsl:param name="obj"/>
|
|
<xsl:param name="edgeElt"/>
|
|
<xsl:param name="crossGraphLinking" select="0"/>
|
|
|
|
<xsl:variable name="fromGraph"
|
|
select="/web:RDF/*[g:hasNode[@web:resource=$nodeURI]]/@web:about"/>
|
|
<xsl:variable name="toGraph"
|
|
select="/web:RDF/*[g:hasNode[@web:resource=$obj]]/@web:about"/>
|
|
|
|
<xsl:if test='$Debug>4'>
|
|
<xsl:message>EdgeProperty:
|
|
pred: <xsl:value-of select='$pred'/>
|
|
obj: <xsl:value-of select='$obj'/>
|
|
from: <xsl:value-of select="$fromGraph"/>
|
|
to: <xsl:value-of select="$toGraph"/>
|
|
</xsl:message>
|
|
</xsl:if>
|
|
|
|
<xsl:if test="($crossGraphLinking = 0 and $fromGraph = $toGraph)
|
|
or ($crossGraphLinking != 0 and $fromGraph != $toGraph)">
|
|
<xsl:text>"</xsl:text>
|
|
<xsl:value-of select='$nodeURI'/>
|
|
<xsl:text>" -> "</xsl:text>
|
|
<xsl:value-of select='$obj'/>
|
|
<xsl:text>"</xsl:text>
|
|
|
|
<xsl:text> [ /* edge attributes */
</xsl:text>
|
|
<!-- edge attributes all except id -->
|
|
<xsl:for-each select='$edgeElt/g:label
|
|
|$edgeElt/g:color
|
|
|$edgeElt/g:constraint
|
|
|$edgeElt/g:decorate
|
|
|$edgeElt/g:dir
|
|
|$edgeElt/g:fontcolor
|
|
|$edgeElt/g:fontname
|
|
|$edgeElt/g:fontsize
|
|
|$edgeElt/g:layer
|
|
|$edgeElt/g:minlen
|
|
|$edgeElt/g:style
|
|
|$edgeElt/g:weight'>
|
|
<!--@@ ...others-->
|
|
<xsl:value-of select='local-name()'/>
|
|
<xsl:text>="</xsl:text>
|
|
<xsl:value-of select='.'/> <!-- @@quoting? -->
|
|
<xsl:text>",
</xsl:text>
|
|
</xsl:for-each>
|
|
|
|
<xsl:for-each select='$edgeElt/*[self::g:lhead or self::g:ltail]'>
|
|
<xsl:variable name="subgraph" select="key('about', @web:resource)"/>
|
|
<xsl:value-of select="local-name()"/>
|
|
<xsl:text>=cluster</xsl:text>
|
|
<xsl:value-of select="generate-id($subgraph)"/>
|
|
<xsl:text>, </xsl:text>
|
|
</xsl:for-each>
|
|
|
|
<xsl:text>];
</xsl:text>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
<!-- don't pass text thru -->
|
|
<xsl:template match="text()|@*">
|
|
</xsl:template>
|
|
|
|
|
|
</xsl:transform>
|