Excel の XML スプレッドシート形式を XSLT で一般的な XML に整形する

1行目を列名とする。
book → シート名 → row → 列名

<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">

<xsl:output method="xml" indent="yes"/>

<xsl:template match="/">
 <xsl:apply-templates select="Workbook" />
</xsl:template>

<!-- 
 ブックの書き出し
 -->
<xsl:template match="Workbook">
 <book>
  <xsl:apply-templates select="Worksheet" />
 </book>
</xsl:template>

<!-- 
 シートの書き出し
 -->
<xsl:template match="Worksheet">
 <xsl:element name="@Name">
   <xsl:apply-templates select="Table/Row">
    <xsl:with-param name="sheetName" select="@Name"/>
   </xsl:apply-templates>
 </xsl:element>
</xsl:template>

<xsl:template match="Row[position()=1]">
</xsl:template>

<!-- 
 行の書き出し
 -->
<xsl:template match="Row">
 <xsl:param name="sheetName" />
  <row>
   <xsl:apply-templates select="Cell">
    <xsl:with-param name="sheetName" select="$sheetName"/>
   </xsl:apply-templates>
  </row>
</xsl:template>

<!-- 
 セルの書き出し
 -->
<xsl:template match="Cell">
 <xsl:param name="sheetName" />
 
 <xsl:variable name="rowIndex" select="position()"/>
 <xsl:variable name="nodename"
  select="/Workbook/Worksheet[@Name=$sheetName]/Table/Row[1]/Cell[$rowIndex]/Data"/>
 <xsl:variable name="data" select="Data"/>
 
 <xsl:if test="$nodename!=''">
  <xsl:if test="$data!=''">
     <xsl:element name="{$nodename}">
      <xsl:value-of select="$data" />
     </xsl:element>
  </xsl:if>
 </xsl:if>
</xsl:template>

</xsl:stylesheet>