After toying with some XPath’s and a fair amount of XSL lately (& getting lost in XPath), I feel it would be wise to place something here to look back on…

Marcus Tucker, introduced me to Stylus Studio of which I am very thankful as XmlSpy didn’t help me to deduce the problem with one of the XPaths, (infact ‘Select Previous Link’)

So heres some snippets.

Select Previous Link – Select First Preceding Node @id with with specified PathID
Select Next Link – Select Following Sibling @id with with specified PathID

Also using the following are very handy for helping you know where abouts you are:
<xsl:copy-of select=”parent::*”>
<xsl:copy-of select=”position()”>

<xsl:template match="*" mode="namespace">
   <xsl:for-each select="namespace::*">
      <xsl:if test="not(../ancestor::*[namespace::*[name() = name(current()) and . = current()]][last()])">
         <xsl:value-of select="name(..)" /> defines <xsl:text />
            <xsl:when test="name()">xmlns:<xsl:value-of select="name()" /></xsl:when>
         <xsl:text />="<xsl:value-of select="." />"<xsl:text />

  <!-- generate namespace declarations as needed for current
	element node and its attributes.
  <xsl:template name="findNamespace">
    <xsl:variable name="curnode" select="." />

    <xsl:for-each select=".|@*">
      <xsl:variable name="vName" select="substring-before(name(), ':')"/>
      <xsl:variable name="vUri" select="namespace-uri(.)"/>

      <xsl:variable name="vAncestNamespace">
        <xsl:call-template name="findAncNamespace">
          <xsl:with-param name="pName" select="$vName"/>
          <xsl:with-param name="pUri" select="$vUri"/>
          <xsl:with-param name="pNode" select="$curnode" />

      <xsl:if test="not(number($vAncestNamespace))">
        <!-- not sure if "parent::*" should be "$curnode/parent::*" -->
        <xsl:if test="parent::* or namespace-uri() or contains(name(), ':')">
          <xsl:text> </xsl:text>
            <xsl:value-of select="'xmlns'"/>
            <xsl:if test="contains(name(), ':')">
              <xsl:value-of select="concat              (':', $vName)"/>
            <xsl:value-of select="namespace-uri()"/>

  <!-- Return 1 if an ancestor of pNode (or an attribute thereof)
    has the same prefix (pName) and namespace-uri (pUri) as
    the current node, and there is no closer ancestor (or attribute
    thereof) that has the same prefix but a different namespace-uri. Return 0 otherwise. -->
  <xsl:template name="findAncNamespace">
    <xsl:param name="pNode" select="."/>
    <xsl:param name="pName" select="substring-before(name(), ':')"/>
    <xsl:param name="pUri" select="namespace-uri(.)"/>

      <xsl:when test="not($pNode/parent::*)">0</xsl:when>
          <xsl:when test="($pNode/.. | $pNode/../@*)
          [$pName = substring-before(name(), ':') and
          $pUri = namespace-uri()]">
          <xsl:when test="($pNode/.. | $pNode/../@*)
          [$pName = substring-before(name), ':')]">
          <!-- and $pUri !=namespace-uri() -->
            <xsl:call-template name="findAncNamespace">
              <xsl:with-param name="pNode" select="$pNode/.."/>
              <xsl:with-param name="pName" select="$pName"/>
              <xsl:with-param name="pUri" select="$pUri"/>


I also wrote up some XSL to retreive parameters from XSL being parsed on the client, now I haven’t tested this although it may be beneficial to someone trying to extract parameters on the client-side.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
  method = "html"
  indent = "no"
  encoding = "UTF-8"

<msxsl:script language="JScript" implements-prefix="eg">
  function GetParam(name) {
    if (start<0)"&"+name+"=");
    if (start<0) return '';
    start += name.length+2;
    if (end<0);
    var result='';

    for(var i=start;i<=end;i++) {
        result=result+(c=='+'?' ':c);
      return unescape(result);

<xsl:template match="/">
  <xsl:value-of select="eg:GetParam('Query')" />