[xsl] xpath / multiple context question

Subject: [xsl] xpath / multiple context question
From: "Angela Williams" <Angela.Williams@xxxxxxxxxxxxxxxxxx>
Date: Tue, 20 Mar 2007 17:22:54 -0500
Xslt 2.0, xpath 2.0, Saxon 8B, XEP 4.4

I don't know an easy way to explain this, so please bear with me. I've scaled
down dramatically, but it's still a little lengthy.

I have a layout xml file that tells me which data values to select and how to
format the numeric values with respect to precision, whether to show the
currency/percent sign, etc. In addition, the data values may be "wrapped" in
text formatting instructions such as font, bold, etc. I use the information in
the layout file with different matching modes to build the header, body, and
footer of my output table.

My problem is this: Once I select my xpath, resolve it to the actual value,
and apply number formatting I need to traverse back up the tree to apply the
text formatting to the formatted number.  I can't just apply-templates because
I lose my specific context.

>> Is there a way to build a result tree starting with the child element and
working up to the parent/grandparent?

Scaled down Examples below - the complete files are at

I apply fruit.xsl to fruit-layout.xml

Desired output:
       <b>$123.00</b> <!--  HERE -->

Actual output:

<?xml version="1.0" encoding="UTF-8"?>

<?xml version="1.0" encoding="UTF-8"?>
    <row-set xpath="doc('fruit-data.xml')/a/b" />
    <order-by xpath="doc('fruit-data.xml')/a/b/c" />

fruit.xsl (abbreviated)
<xsl:stylesheet exclude-result-prefixes="#all"


  <xsl:template match="columns">
    <xsl:variable name="cols" select="." /> <!-- outer context -->

    <xsl:variable name="rows" as="xs:string">
      <xsl:value-of select="../data-set/row-set/@xpath" />

    <xsl:variable name="sort" as="xs:string">
      <xsl:value-of select="../data-set/order-by/@xpath" />

    <xsl:for-each select="sax:eval(sax:expression($rows))">
      <xsl:sort select="sax:eval(sax:expression(substring-after($sort,
concat($rows, '/'))))" />

      <xsl:variable name="node" select="." /> <!-- data element context -->
        <xsl:for-each select="$cols/column">

            <xsl:variable name="field">  <!-- value context -->
              <xsl:value-of select="data-value/descendant::xpath" />

            <xsl:variable name="amt" as="xs:string"
select="$node/sax:evaluate(substring-after($field, concat($rows,'/')))" />

              <xsl:variable name="precision" as="xs:integer">
                <logic />

              <!-- The following line produces the child data value.
                   How do I wrap this with the parent <b> element? -->
select="fc:nbr-format(number($amt),$precision,'true','$')" />


  <xsl:template match="bold">
      <xsl:apply-templates />

  <xsl:template match="xpath">
    <!-- This is where I need the child data value to print in the result
         If I just match here, I lose the context and get ALL xpath values,
         I only want the formatted child data value resolved in the columns


Thanks in advance!
Angela Williams
Channel Developer
The 401k Company - Austin, Texas

Current Thread