I have a table schema which has some meta field data which I need to pull down to the row level.
So this …
<tables>
<table name="T01">
<columns>
<column name="F01">
<heading>Field 1</heading>
</column >
<column name="F02">
<heading>Field 2</heading>
</column>
</columns>
<rows>
<row>
<field name="F01">AAAAA</field>
<field name="F02">BBBBB</field>
</row>
<row>
<field name="F01">DDDDD</field>
<field name="F02">EEEEE</field>
</row>
</rows>
</table>
<table name="T02">
<!-- ... -->
</table>
</tables>
should become this …
<tables>
<table name="T01">
<rows>
<row>
<field name="F01">
<heading>Field 1</heading>
<value>AAAAA</value>
</field>
<field name="F02">
<heading>Field 2</heading>
<value>BBBBB</value>
</field>
</row>
<row>
<field name="F01">
<heading>Field 1</heading>
<value>DDDDD</value>
</field>
<field name="F02">
<heading>Field 2</heading>
<value>EEEEE</value>
</field>
</row>
</rows>
</table>
<table name="T02">
<!-- ... -->
</table>
</tables>
I am sure there are tons of simple ways to do this with XSLT, but due to my tool, I really need to retrieve the column heading via a key(). So something like this …
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<!-- This won't work but if it did ... -->
<xsl:key name="field-heading"
match="../../columns/column/heading"
use="../@name" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="field">
<field name="{@name}">
<heading>
<xsl:value-of select="key('field-heading', @name)"/>
</heading>
<value>
<xsl:value-of select="."/>
</value>
</field>
</xsl:template>
<xsl:template match="columns"/>
</xsl:stylesheet>
But the xsl:key match attribute doesn’t allow the parent axis and I am not sure if there are any other ways make it fit.
A slightly simpler solution:
When this transformation is applied on the provided XML document:
the wanted, correct result is produced:
Explanation: Overriding the identity rule and using a composite key — a
columnis identified by the pair of itsnameattribute and thenameattribute of its grandparenttable.