Subject: Continuous path of elements satisfying a condition
From: <cgp@xxxxxxxxxxx>
Date: Sat, 18 Dec 2004 12:37:59 -0500
|
I have input like this:
<root>
<item id="1">
<item id="2">
<item id="3"/>
<item/>
</item>
<item>
<item/>
</item>
<item id="4"/>
</item>
<item>
<item/>
</item>
</root>
I am only interested in item elements that have id attributes and form a continuous chain
from the child of the root element to a leaf.
1) I can select the leaves and then all the relevant items with
<xsl:variable name="leaves" select="//item[@id and not(*) and not (ancestor::item[not(@id)])]"/>
<xsl:variable name="items" select="$leaves | $leaves/ancestor::item"/>
Is there a better way?
2) In the template for an item, I need to loop through the item's children that meet the
conditions (i.e., that are in $items). I've tried this
<xsl:variable name="nitems" select="count($items)"/>
<xsl:template match="/">
<xsl:apply-templates select="$items"/>
</xsl:template>
<xsl:template match="item">
<xsl:for-each select="item[count(. | $items) = $nitems]">
...
</xsl:text>
</xsl:for-each>
</xsl:template>
This is fairly elegant but testing in my environment (MSXML) shows it to take 4 seconds
while a recursive template that just sums the number of included items that are
children of the current item runs about 50 lines but takes half the time to run.
Thanks,
Chris
|