次のようなサンプルの xml 入力があります。
<table name="Table1">
<fields>
<field name="Field1" />
<field name="Field2" />
<field name="Field3" />
<field name="Field4" />
</fields>
<data>
<row value="2,Description1,A,AA" />
<row value="3,Description2,B,BB" />
<row value="7,Description3,C,CC" />
</data>
</table>
<table name="Table2">
<fields>
<field name="Field7" />
<field name="Field8" />
<field name="Field9" />
</fields>
<data>
<row value="Q,Description7,A" />
<row value="W,Description8,B" />
<row value="X,Description9,C" />
</data>
</table>
フィールドの数が異なる多くのテーブルを持つことができますが、行の値には常に必要なフィールドの正確な数が含まれていることに注意してください。
期待される結果は、次のような出力です。
<ListOfTable1>
<item>
<Field1>2</Field1>
<Field2>Description1</Field2>
<Field3>A</Field3>
<Field4>AA</Field4>
</item>
<item>
<Field1>3</Field1>
<Field2>Description2</Field2>
<Field3>B</Field3>
<Field4>BB</Field4>
</item>
<item>
<Field1>7</Field1>
<Field2>Description3</Field2>
<Field3>C</Field3>
<Field4>CC</Field4>
</item>
</ListOfTable1>
<ListOfTable2>
<item>
<Field7>Q</Field7>
<Field8>Description7</Field8>
<Field9>A</Field9>
</item>
<item>
<Field7>W</Field7>
<Field8>Description8</Field8>
<Field9>B</Field9>
</item>
<item>
<Field7>X</Field7>
<Field8>Description9</Field8>
<Field9>C</Field9>
</item>
</ListOfTable2>
残念ながら厳密な XSLT 1.0 しか使用できません 外部関数や参照はありません
提案された3番目のソリューションのわずかに変更されたバージョンを使用しています
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="//table">
<xsl:value-of disable-output-escaping="yes" select="concat('<ListOf',@name,'>')" />
<xsl:apply-templates />
<xsl:value-of disable-output-escaping="yes" select="concat('</ListOf',@name,'>')" />
</xsl:template>
<xsl:template match="table/data/row">
<item>
<xsl:call-template name="fldsplit">
<xsl:with-param name="f" select="@value" />
<xsl:with-param name="set" select="//fields/field" />
</xsl:call-template>
</item>
</xsl:template>
<xsl:template name="fldsplit">
<xsl:param name="f" />
<xsl:param name="set"/>
<xsl:variable name="bfc" select="substring-before($f,',')"/>
<xsl:variable name="afc" select="substring-after($f,',')"/>
<xsl:element name="{$set/@name}">
<xsl:choose>
<xsl:when test="$bfc">
<xsl:value-of select="$bfc"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$f"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
<xsl:if test="$afc">
<xsl:call-template name="fldsplit">
<xsl:with-param name="f" select="$afc"/>
<xsl:with-param name="set" select="$set/following-sibling::*" />
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
しかし、2 番目のテーブル (または入力に追加するその他のテーブル) に問題があります。つまり、フィールド名は常に Field1 から始まり、解析される各テーブルに特定のフィールドを使用することを期待しています。
これは現在の出力です(間違っています)
<?xml version="1.0" encoding="UTF-8"?>
<ListOfTable1>
<item><Field1>2</Field1><Field2>Description1</Field2><Field3>A</Field3><Field4>AA</Field4></item>
<item><Field1>3</Field1><Field2>Descritpion2</Field2><Field3>B</Field3><Field4>BB</Field4></item>
<item><Field1>7</Field1><Field2>Description3</Field2><Field3>C</Field3><Field4>CC</Field4></item>
</ListOfTable1>
<ListOfTable2>
<item><Field1>Q</Field1><Field2>Description7</Field2><Field3>A</Field3></item>
<item><Field1>W</Field1><Field2>Description8</Field2><Field3>B</Field3></item>
<item><Field1>X</Field1><Field2>Description9</Field2><Field3>C</Field3></item>
</ListOfTable2>