rowan(_at_)sylvester-bradley(_dot_)org wrote:
<?xml version="1.0" encoding="UTF-8"?>
<items>
<item>
<name>First</name>
<level>0</level>
<ref/>
<contents>First contents.</contents>
</item>
<item>
<name>Second</name>
<level>1</level>
<ref/>
<contents>Second contents.</contents>
</item>
<item>
<name>Third</name>
<level>2</level>
<ref/>
<contents>Third contents.</contents>
</item>
<item>
<name>Fourth</name>
<level>3</level>
<ref/>
<contents>Fourth contents.</contents>
</item>
<item>
<name>Fifth</name>
<level>1</level>
<ref/>
<contents>Fifth contents.</contents>
</item>
<item>
<name>Sixth</name>
<level>2</level>
<ref>Third</ref>
<contents>Sixth contents.</contents>
</item>
<item>
<name>Seventh</name>
<level>1</level>
<ref/>
<contents>Seventh contents.</contents>
</item>
</items>
When I find an item with an empty <ref> element, I want to just copy it to
the putput. But when I find one with a non-empty <ref> element, I want to
copy <item>s in sequence, starting with the one whose <name> matches the
<ref> of the source <item> (I'll call this the start item), and finishing
with the last one whose <level> value is greater than the <level> of the
start item. So I want to stop just before the <item> whose <level> is <=
the <level> of the start item.
What I want to produce from the above file is:
<?xml version="1.0" encoding="UTF-8"?>
<items>
<item>
<name>First</name>
<level>0</level>
<ref/>
<contents>First contents.</contents>
</item>
<item>
<name>Second</name>
<level>1</level>
<ref/>
<contents>Second contents.</contents>
</item>
<item>
<name>Third</name>
<level>2</level>
<ref/>
<contents>Third contents.</contents>
</item>
<item>
<name>Fourth</name>
<level>3</level>
<ref/>
<contents>Fourth contents.</contents>
</item>
<item>
<name>Fifth</name>
<level>1</level>
<ref/>
<contents>Fifth contents.</contents>
</item>
<item>
<name>Third</name>
<level>2</level>
<ref/>
<contents>Third contents.</contents>
</item>
<item>
<name>Fourth</name>
<level>3</level>
<ref/>
<contents>Fourth contents.</contents>
</item>
<item>
<name>Seventh</name>
<level>1</level>
<ref/>
<contents>Seventh contents.</contents>
</item>
</items>
Assuming XSLT 2.0 I tried to implement your description as follows:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:key name="k1" match="item" use="name"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="item[normalize-space(ref)]">
<xsl:variable name="si" select="key('k1', ref)[1]"/>
<xsl:copy-of select="$si | $si/following-sibling::item[. <<
$si/following-sibling::item[level <= $si/level][1]]"/>
</xsl:template>
</xsl:stylesheet>
For the input sample you provided that produces the result you describe.
--
Martin Honnen
http://msmvps.com/blogs/martin_honnen/
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--