Paul
Paul

Reputation: 3954

XSLT dynamic attribute inside for-each

I'm working on an XSLT file to transform an XML doc that represents a table into SQL commands. The XML describes both the table's columns and each row of data with the following structure:

<Table>
<ObjectAttributes>
  <AttributeDetail>
    <Name>COLNAME1</Name>
    ...
  </AttributeDetail>
  <AttributeDetail>
    <Name>COLNAME2</Name>
    ...
  </AttributeDetail>
  ...
</ObjectAttributes>
<Record RowID="00001">
  <Attributes>
    <Attr>
      <AttrName>COLNAME1</AttrName>
      <AttrValue>VALUE</AttrValue>
    </Attr>
    <Attr>
      <AttrName>COLNAME2</AttrName>
      <AttrValue>VALUE</AttrValue>
    </Attr>
    ...
  </Attributes>
</Record>
<Record RowID="00002">
  <Attributes>
    <Attr>
      <AttrName>COLNAME1</AttrName>
      <AttrValue>VALUE</AttrValue>
    </Attr>
    <Attr>
      <AttrName>COLNAME2</AttrName>
      <AttrValue>VALUE</AttrValue>
    </Attr>
    ...
  </Attributes>
</Record>
...
</Table>

I've written the following XSLT to create INSERT commands:

<xsl:for-each select="/Table/Record">
  <xsl:variable name="ThisRecord" select="."/>
  <Command>
    INSERT INTO <xsl:value-of select="../ObjectName"/>
      (ROWID, 
      <xsl:for-each select="../ObjectAttributes/AttributeDetail">
        <xsl:value-of select="Name"/>
        <xsl:if test="position() != last()">
          <xsl:text>, </xsl:text>
        </xsl:if>
      </xsl:for-each>) 
      VALUES 
      (<xsl:value-of select="@RowID"/>, 
      <xsl:for-each select="../ObjectAttributes/AttributeDetail">
        <xsl:text>'</xsl:text><xsl:value-of select="$ThisRecord/Attributes/Attr/AttrValue[../AttrName='COLNAME1']"/><xsl:text>'</xsl:text>
        <xsl:if test="position() != last()">
          <xsl:text>, </xsl:text>
        </xsl:if>
      </xsl:for-each>)
  </Command>
</xsl:for-each>

This works great except for the fact that I'm struggling to figure out how to replace the value for AttrName='' with the value that would result from:

<xsl:value-of select="Name"/>

I've tried replacing it with a variable, but this did not work:

<xsl:variable name="ThisAttr" select="Name"/>
<xsl:value-of select="$ThisRecord/Attributes/Attr/AttrValue[../AttrName='$ThisAttr']"/>

How can I fill in this attribute dynamically?

Thanks!

Upvotes: 1

Views: 2016

Answers (1)

Wayne
Wayne

Reputation: 60414

You can reference the current context node with current():

<xsl:value-of 
    select="$ThisRecord/Attributes/Attr[AttrName=current()/Name]/AttrValue"/>

I should note that your variable approach would have worked without the quotes around the variable reference in AttrName='$ThisAttr'. You're literally matching on the string $ThisAttr (i.e. not referencing any variable); you should have used AttrName=$ThisAttr (no quotes).

That said, using current() is the better solution.

(Note that I also re-arranged the expression steps so that no backtracking is required.)

Upvotes: 3

Related Questions