I am trying to do something that may seem irrational, but I have the reasons for such a request.
Hoped to create a nested for-each loop which will continue from the outer for-each or start over, as in the following example.
The following is the input xml, this input represents the structure I am working with, but with dummy data. XML:
<table>
<Row>
<Field name="ver">1</field>
<Field name="isNewVersion">1</field>
<Field name="sub">a</field>
</Row>
<Row>
<Field name="ver">1</field>
<Field name="isNewVersion">0</field>
<Field name="sub">b</field>
</Row>
<Row>
<Field name="ver">1</field>
<Field name="isNewVersion">0</field>
<Field name="sub">c</field>
</Row>
<Row>
<Field name="ver">2</field>
<Field name="isNewVersion">1</field>
<Field name="sub">x</field>
</Row>
<Row>
<Field name="ver">2</field>
<Field name="isNewVersion">0</field>
<Field name="sub">y</field>
</Row>
</table>
The outer for-each works fine, but can't seem to make the nested for-each to work. Is there a way to me it iterate over:
The rest of the <field>
tags (continue where it was left off by the outer for-each)
OR
Start from the beginning of the entire input xml
XSLT:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<Main>
<xsl:for-each select="table/Row">
<xsl:if select="field[@name='isNewVersion'] = 1"> <!--check if first sub per new version-->
<Data ver="{field[@name='ver'}">
<xsl:variable name="currentVer" select="{field[@name='ver'}" /> <!--saved for nested for-each-->
<xsl:for-each select="..."> <!--This is the problem, would like to iterate from the start of xml-->
<xsl:if select="{field[@name='ver'] = currentVer}"> <!--check if came to new version-->
<Sub id="{field[@name='sub']}" />
</xsl:if>
</xsl:for-each>
</Data>
</xsl:if>
</xsl:for-each>
</Main>
</xsl:template>
</xsl:stylesheet>
This is how I would like the final (output) xml to look like. The Output I would like:
<Main>
<Data ver="1">
<Sub id="a" />
<Sub id="b" />
<Sub id="c" />
</Data>
<Data ver="2">
<Sub id="x" />
<Sub id="y" />
</Data>
</Main>
Thanks for any help :)
CodePudding user response:
Try it this way:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="row-by-ver" match="Row" use="field[@name='ver']" />
<xsl:template match="/table">
<Main>
<xsl:for-each select="Row[field[@name='isNewVersion'] = 1]">
<xsl:variable name="version" select="field[@name='ver']" />
<Data ver="{$version}">
<xsl:for-each select="key('row-by-ver', $version)">
<Sub id="{field[@name='sub']}" />
</xsl:for-each>
</Data>
</xsl:for-each>
</Main>
</xsl:template>
</xsl:stylesheet>
Note:
XML is case-sensitive. field
is not the same as Field
and your input will produce an error on every line of:
<Field name="x">y</field>