Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

XSLT not following path in for-each 1

Status
Not open for further replies.

tshad

Programmer
Jul 15, 2004
386
US
I need to go back up a level (or 2) when in a for-each loop. The loop works fine when using name() and "." but doesn't seem to work for "../@something".

If you look in my example you will see "../@ID" before the for-each and after the for-each. I get a value for the first one but not the second.

Code:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform"[/URL]    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/*">
    <xsl:copy>
      <xsl:apply-templates select="METHODS/COMPARISON">
        <xsl:with-param name="reportName" select="REPORT/@MajorFormType"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

  <!-- Now we handle the other sections after the DATA section -->

  <xsl:template match="COMPARISON">
    <xsl:param name="reportName"/>
    <xsl:apply-templates>
      <xsl:with-param name="reportName" select="$reportName"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="SALE">
    <xsl:param name="reportName"/>
    <xsl:value-of select="../@ID"/>    <!-- Works Here -->
    <xsl:for-each select="@*">
      <form>
        <ID>
          <xsl:value-of select="../@ID"/>  <!-- Does Not Work Here -->
        </ID>
        <section>
          <xsl:text>0</xsl:text>
        </section>
        <formName>
          <xsl:value-of select="$reportName"/>
        </formName>
        <tagName>
          <xsl:value-of select="name()"/>
        </tagName>
        <value>
          <xsl:value-of select="."/>
        </value>
      </form>
    </xsl:for-each>
    <xsl:apply-templates>
      <xsl:with-param name="reportName" select="$reportName"/>
    </xsl:apply-templates>
  </xsl:template>
 </xsl:stylesheet>

If you look at the results you will see "241" which is the value before the for-each and 3 <ID></ID>. These should show as <ID>241</ID>.

Code:
<?xml version="1.0" encoding="utf-8"?>
<RESPONSE>
  241
  <form>
    <ID></ID>
    <section>0</section>
    <formName>Form102</formName>
    <tagName>SequenceId</tagName>
    <value>0</value>
  </form><form>
    <ID></ID>
    <section>0</section>
    <formName>Form102</formName>
    <tagName>state</tagName>
    <value>true</value>
  </form><form>
    <ID></ID>
    <section>0</section>
    <formName>Form102</formName>
    <tagName>saleDate</tagName>
    <value>05/15/2011</value>
  </form>
</RESPONSE>

Why does this not work?

Thanks,

Tom
 
I found I can set up a variable and it would work inside the for-each. But I would rather access it directly.

Here is the changed code where I set up a variable "temp":

Code:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform"[/URL]    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/*">
    <xsl:copy>
      <xsl:apply-templates select="METHODS/COMPARISON">
        <xsl:with-param name="reportName" select="REPORT/@MajorFormType"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

  <!-- Now we handle the other sections after the DATA section -->

  <xsl:template match="COMPARISON">
    <xsl:param name="reportName"/>
    <xsl:apply-templates>
      <xsl:with-param name="reportName" select="$reportName"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="SALE">
    <xsl:param name="reportName"/>
    <xsl:variable name="temp" select="../@ID"/>
    <xsl:value-of select="../@ID"/>    <!-- Works Here -->
    <xsl:for-each select="@*">
      <form>
        <var>
          <xsl:value-of select="$temp"/>
        </var>
        <ID>
          <xsl:value-of select="../@ID"/>  <!-- Does Not Work Here -->
        </ID>
        <section>
          <xsl:text>0</xsl:text>
        </section>
        <formName>
          <xsl:value-of select="$reportName"/>
        </formName>
        <tagName>
          <xsl:value-of select="name()"/>
        </tagName>
        <value>
          <xsl:value-of select="."/>
        </value>
      </form>
    </xsl:for-each>
    <xsl:apply-templates>
      <xsl:with-param name="reportName" select="$reportName"/>
    </xsl:apply-templates>
  </xsl:template>
 </xsl:stylesheet>

Here is the result I get from this:

Code:
<?xml version="1.0" encoding="utf-8"?>
<RESPONSE>
  241
    <form>
    <var>241</var>
    <ID></ID>
    <section>0</section>
    <formName>Form102</formName>
    <tagName>SequenceId</tagName>
    <value>0</value>
  </form><form>
    <var>241</var>
    <ID></ID>
    <section>0</section>
    <formName>Form102</formName>
    <tagName>state</tagName>
    <value>true</value>
  </form><form>
    <var>241</var>
    <ID></ID>
    <section>0</section>
    <formName>Form102</formName>
    <tagName>saleDate</tagName>
    <value>05/15/2011</value>
  </form>
</RESPONSE>

Thanks,

Tom
 
The for-each changes the context node. So, your Xpath expression must adjust accordingly. Since the context inside the for-each is an attribute node, ../@ID is looking for sibling attribute (on the SALE node because the .. gets you back to the SALE node), not for an attribute on the parent of SALE. Try ../../@ID and see what happens.

Tom Morrison
Micro Focus
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top