Am new to XSLT and am just not able to wrap my head around this one. I have an XML as follows:
<root>
<key>1</key>
<list>
<value>1</value>
<value>2</value>
</list>
</root>
What I want to achieve is this:
<root>
<row>
<key>1</key>
<value>1</value>
</row>
<row>
<key>1</key>
<value>2</value>
</row>
</root>
Your requirements are not entirely clear, but let's give it a try:
<xsl:template match="/root">
<xsl:copy>
<!-- each first following sibling after <key> -->
<xsl:apply-templates select="key/following-sibling::list[1]" />
</xsl:copy>
</xsl:template>
<xsl:template match="list">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="value">
<row>
<!-- the key immediately before the current <list> -->
<xsl:copy-of select="ancestor::list/preceding-sibling::key[1]" />
<xsl:copy-of select="." />
</row>
</xsl:template>
This code assumes a basic understanding of XSLT. And it assumes my understanding that a list
element is preceded directly by a key
element and that each row/value
becomes a row
with a value
and the preceding key
.
You tagged your question XSLT 2.0, but this code works with either XSLT 1.0 or 2.0 (and in this particular case will not be very different if you tried using the 2.0 features).
Tested with a 1.0 (.NET) and two 2.0 (Exselt and Saxon) processors against the following modified input:
<root>
<key>1</key>
<list>
<value>1</value>
<value>2</value>
</list>
<key>2</key>
<list>
<value>55</value>
<value>66</value>
<value>77</value>
</list>
</root>
Resulting in the following output:
<root>
<row>
<key>1</key>
<value>1</value>
</row>
<row>
<key>1</key>
<value>2</value>
</row>
<row>
<key>2</key>
<value>55</value>
</row>
<row>
<key>2</key>
<value>66</value>
</row>
<row>
<key>2</key>
<value>77</value>
</row>
</root>