Finding Specific Descendant Nodes With XSL:Key
Question
Given the following code:
<database>
<table name="table1">
<column name="id"/>
<column name="created_at"/>
</table>
<table name="table2">
<column name="id"/>
<column name="updated_at"/>
</table>
</database>
I want to be able to test using an xsl:key if specific table has a specific column by name. For instance, I want to know if a table has a 'created_at' column so I can write specific code within the transformation.
I've gotten a general key that will test if any table has a given column by name, but have not figured out how to make it specific to the table the transformation is currently working with.
<xsl:key name="columnTest" match="column" use="@name"/>
<xsl:for-each select="database/table">
<xsl:choose>
<xsl:when test="key('columnTest', 'created_at')">
<xsl:text>true</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>false</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
So I end up with 'true' for all the tables. Any guidance would be appreciated.
Solution
The following transformation shows how this can be done:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kTableByName"
match="table" use="@name"/>
<xsl:key name="kColumnByTable"
match="column" use="concat(generate-id(..), '+', @name)"/>
<xsl:template match="/">
<xsl:value-of select=
"boolean(key('kColumnByTable',
concat(generate-id(key('kTableByName', 'table1')),
'+',
'created_at'
)
)
)
"/>
<xsl:text>
</xsl:text>
<xsl:value-of select=
"boolean(key('kColumnByTable',
concat(generate-id(key('kTableByName', 'table1')),
'+',
'updated_at'
)
)
)
"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document, the wanted, correct result is produced:
true
false
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow