How it works ...
On Monday, March 31, 2003, at 06:02 PM, S Woodside wrote:
It's a recursive template, $fragment gets ever shorter, it pulls steps
off the front of the string.
<!-- Converts an instance path to an RNG path -->
<xsl:template name="inst2rngPath">
<xsl:param name="fragment"/>
fragment must be an XPath string from an instance document that
conforms to a given RNG grammar
<xsl:choose>
<xsl:when test="starts-with($fragment, '/')"> <!-- strip
beginning / -->
<xsl:call-template name="inst2rngPath">
<xsl:with-param name="fragment"
select="substring-after($fragment, '/')"/>
</xsl:call-template>
</xsl:when>
That section eliminates any leading "/" if there is one and recurses
without it.
This section inserts //*[(_at_)name=' ... (since the instance node steps
are encoded into the RNG as attributes called "name"). There can be
arbitrary steps inbetween name-defining nodes in RNG that might define
optional, zeroOrMore, etc. so // just skips them.
<xsl:otherwise>
<xsl:text>//*[(_at_)name='</xsl:text>
this section coming up will insert a single step in the XPath.
<xsl:choose>
<xsl:when test="substring-before($fragment, '/')">
<xsl:value-of select="substring-before($fragment, '/')"/>
</xsl:when><xsl:otherwise>
<xsl:value-of select="$fragment"/>
</xsl:otherwise></xsl:choose>
<xsl:text>']</xsl:text>
It used a choose because the substring-before() xpath function returns
nothing if the "before" string isn't found (as opposed to returning the
whole string) so that if this is the last recursive step, and there is
no "/" it will just select $fragment
Now we will either recurse if there's something left to process, or
stop recursing
<xsl:choose>
<xsl:when test="contains($fragment, '/')"> <!-- recursive
step -->
<xsl:call-template name="inst2rngPath">
<xsl:with-param name="fragment"
select="substring-after($fragment, '/')"/>
</xsl:call-template>
that recursed after snipping off the first node step
</xsl:when><xsl:otherwise> <!-- default step -->
<xsl:text>/*</xsl:text>
</xsl:otherwise>
that add /* to the end to select all children (maybe not necessary
though)
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
That's all.
simon
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list