Re: [xsl] this script converts an instance path to an RNG path

Subject: Re: [xsl] this script converts an instance path to an RNG path
From: S Woodside <sbwoodside@xxxxxxxxx>
Date: Mon, 31 Mar 2003 18:42:21 -0500
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 //*[@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>//*[@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



Current Thread