[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
http://www.mwpoa.com/angela/xpathContextQuestion.html:

I apply fruit.xsl to fruit-layout.xml

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

Actual output:
<snip>
   <td>
     <p>$123.00</p>
   </td>
</snip>

fruit-data.xml:
<?xml version="1.0" encoding="UTF-8"?>
<a>
  <b>
    <c>apple</c>
    <d>123.000000</d>
  </b>
</a>

fruit-layout.xml:
<?xml version="1.0" encoding="UTF-8"?>
<table>
  <data-set>
    <row-set xpath="doc('fruit-data.xml')/a/b" />
    <order-by xpath="doc('fruit-data.xml')/a/b/c" />
  </data-set>
  <columns>
    <column>
      <format>
        <type>currency</type>
        <precision>2</precision>
        <show-sign>first-and-last</show-sign>
      </format>
      <data-value>
        <bold>
          <xpath>doc('fruit-data.xml')/a/b/d</xpath>
        </bold>
      </data-value>
    </column>
  </columns>
</table>

fruit.xsl (abbreviated)
<xsl:stylesheet exclude-result-prefixes="#all"
  xmlns:xs="http://www.w3.org/2001/XMLSchema";
  xmlns:fc="http://www.myfruit.com/fruit";
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  xmlns:sax="http://saxon.sf.net/";
  version="2.0">

  <snip>

  <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>

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

    <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 -->
      <tr>
        <xsl:for-each select="$cols/column">

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

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

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

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

        </xsl:for-each>
      </tr>
    </xsl:for-each>
  </xsl:template>


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

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

</xsl:stylesheet>


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

Current Thread