Subject: [xsl] Finding paths in Visio XML exports - recursion question From: Steven Davies <xsl-list@xxxxxxxxxxx> Date: Sat, 27 Sep 2008 20:20:25 +0100 |
while I'm not a total XSLT newbie I'm having trouble getting my head round a couple of things when trying to find paths through Visio flowcharts which have been exported in Visio's XML format.
Very basically, for anyone who is unaware of Visio's schema I shall try to describe it below with a very simplified example:
<Pages> <Page ID="1"> <Shapes> <Shape ID="1" NameU="CustomShape.112"> <Shape-specific-data /> </Shape> <Shape ID="2" NameU="CustomShape.8"> <Shape-specific-data /> </Shape> <Shape ID="3" NameU="CustomShape.32"> <Shape-specific-data /> </Shape> </Shapes> <Connects> <Connect FromSheet="1" FromCell="BeginX" ToSheet="1" /> <Connect FromSheet="1" FromCell="EndX" ToSheet="2" /> <Connect FromSheet="2" FromCell="BeginX" ToSheet="2" /> <Connect FromSheet="2" FromCell="EndX" ToSheet="3" /> </Connects> </Page> </Pages>
Obviously there are many more <Shape>s and <Connect>s in the document! The <Connect>s map from a <Shape> whose ID is the same as @ToSheet and @FromCell="BeginX" to a <Shape> whose ID is the same as @ToSheet and @FromCell="EndX".
Now, I can use an XPath expression to find the first node in the document easily enough (it has a certain property in its data set to "1") and the only way I've been able to find all connected shapes from this one is to use 3 for-each loops: the first over all <Connect>s beginning at the shape itself, the second nested loop over all other endpoints of the <Connect> (there will only ever be one) and the third over all <Shape>s connected to the <Connect>:
<xsl:variable name="thisShapeID" select="./@ID"/> <xsl:for-each select="../../v:Connects/v:Connect[@ToSheet=$thisShapeID and @FromCell='BeginX']"> <xsl:variable name="connectFromSheet" select="./@FromSheet"/> <xsl:for-each select="../v:Connect[@FromSheet=$connectFromSheet and @FromCell='EndX']"> <xsl:variable name="nextShapeID" select="./@ToSheet"/> <xsl:for-each select="../../v:Shapes/v:Shape[@ID=$nextShapeID]">
Inside the innermost xsl:for-each I recursively call the template which works very well for a straight flow in Visio. However, there can be infinite loops in the flow so I have to first test whether the <Shape> has already been output before recursing. This works.
Also the flows can branch off in multiple directions and each branch needs to be output one at a time (i.e. the nodes before the branch only need to be output once). This also works.
Many thanks if you got this far ;-) Steve
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Is a variable referencing, Andrew Welch | Thread | Re: [xsl] Finding paths in Visio XM, G. Ken Holman |
Re: [xsl] Is a variable referencing, Mukul Gandhi | Date | Re: [xsl] Finding paths in Visio XM, G. Ken Holman |
Month |