tags:

views:

289

answers:

2

--edited for clarity (hopefully)

I have an XML file that looks something like this:

<questionBlock>
    <responses>
      . . .
      <response>
        <degree>1</degree>
        <instdegree>1</instdegree>
      </response>
      . . .
   </responses>
   <question>
      <variable>degree</variable>
      <text>Please select a degree or credential you have pursued.</text>
      <responses>
        <response>
          <label>High School Diploma</label>
          <value>1</value>
        </response>
        <response>
          <label>Certificate</label>
          <value>2</value>
        </response>
      </responses>
      . . .
   </question>
</questionBlock>

A subset of the XSLT looks like this:

 . . .
<xsl:for-each select="responses/response">
   <xsl:variable name="paddedCount" select="concat('00',position())"/>
   <xsl:variable name="s" select="substring($paddedCount,string-length($paddedCount)-1,string-length($paddedCount))"/>
   <xsl:variable name="degree" select="degree" />
. . . 
In addition to selecting the value of the degree (1), I also want to be able to select the "High School Diploma" based on that value, but I haven't been able to think through the XPath to do this in the general case (e.g., if degree equals 2).

Any help would be much appreciated. Thanks.

+2  A: 

EDIT: I guess you mean something like this?

<xsl:for-each select="responses/response">
  <xsl:variable name="degree" select="degree" />    
  <xsl:variable name="degree-response" select="
    ../question[variable = 'degree']/responses/response[value = $degree]
  " />
  <xsl:value-of select="$degree-response/label" />
</xsl:for-each>

Really, you should try to refactor all of this to <xsl:apply-templates> instead of <xsl:for-each>. The for-each sucks in more ways than one, and it makes things harder than they should be. See: "Using xsl:for-each is almost always wrong"

For-each has it's uses, but all "regular" processing should be done through apply-templates.


Original version of the answer (for reference only, since OP has modified the question):

When the context node is <degree>1</degree>:

parent::condition/following-sibling::responses[1]/response[1]/label

or, shorter:

../following-sibling::responses[1]/response[1]/label
Tomalak
Thanks, Tomalak. You're quite right, of course, about avoiding for-each. The XSLT was written by a junior programmer (without any experience with functional programming), and I needed to fix it quickly to solve a problem. I really need to go back and refactor the whole thing.
Jason Francis
+2  A: 

The xpath: ../../responses[response=current()]/label

Gregoire
Worked beautifully, thanks.
Jason Francis