Subject: Re: Best Way to Select Following Elements With An Ancestor?
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Sat, 22 Mar 2014 15:58:09 -0700
|
I suspect that something like this might be quite efficient (using
keys) in the case the search is performed for more than one descendant
of a subtree top-node:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kDescendants" match="computer//*"
use="generate-id(ancestor::computer[1])"/>
<xsl:template match="/*">
<xsl:apply-templates select="computer[2]/motherboard"/>
</xsl:template>
<xsl:template match="computer[2]/motherboard">
<xsl:sequence select=
"key('kDescendants', generate-id(ancestor::computer[1]))
[. >> current()]"/>
</xsl:template>
</xsl:stylesheet>
When the transformation is applied on the following XML document (none
was originally provided):
<computers>
<computer>
<cpu ghz="3.5" unlocked="Yes">Intel i7 3770k</cpu>
<motherboard>MSI M-Power</motherboard>
<ram>8</ram>
<storage>
<hdd>1000</hdd>
<ssd>128</ssd>
</storage>
<gpu group="ATI">7950</gpu>
<psu>750</psu>
</computer>
<computer>
<cpu ghz="3.5" unlocked="Yes">Intel i5 3570k</cpu>
<motherboard>ASRock Extreme 4</motherboard>
<ram>8</ram>
<storage>
<hdd>1000</hdd>
</storage>
<gpu group="ATI">7870</gpu>
<psu>600</psu>
</computer>
<computer>
<cpu ghz="3.5" unlocked="No">Intel i5 3550</cpu>
<motherboard>ASRock Extreme 3</motherboard>
<ram>8</ram>
<storage>
<hdd>500</hdd>
</storage>
<gpu group="GeForce">9600GT</gpu>
<psu>500</psu>
</computer>
</computers>
we get exactly the wanted result:
<ram>8</ram>
<storage>
<hdd>1000</hdd>
</storage>
<hdd>1000</hdd>
<gpu group="ATI">7870</gpu>
<psu>600</psu>
On Sat, Mar 22, 2014 at 5:46 AM, Eliot Kimber <ekimber@xxxxxxxxxxxx> wrote:
> I have a document where each child of the root element establishes a
> unique content with regard to the output result (in this case,
> corresponding to InDesign frames).
>
> For a given descendant of one of these elements I need to know if there
> are any following elements within the same context. So simply doing
> following::* won't work and the following elements I'm checking for need
> not be siblings of the current element.
>
> The solution I arrived at is:
>
> <xsl:variable name="myDitaAncestor" select="ancestor::dita"
> as="element()*"/>
>
> <xsl:variable name="followingWithinDita" as="element()*"
> select="following::*[count(ancestor::dita | $myDitaAncestor) = 1]"
> />
>
> This works but I'm wondering if there's a better solution, either one that
> is more efficient or one that is more elegant?
>
>
> Thanks,
>
> Eliot
> bbbbb
> Eliot Kimber, Owner
> Contrext, LLC
> http://contrext.com
>
--
Cheers,
Dimitre Novatchev
---------------------------------------
Truly great madness cannot be achieved without significant intelligence.
---------------------------------------
To invent, you need a good imagination and a pile of junk
-------------------------------------
Never fight an inanimate object
-------------------------------------
To avoid situations in which you might make mistakes may be the
biggest mistake of all
------------------------------------
Quality means doing it right when no one is looking.
-------------------------------------
You've achieved success in your field when you don't know whether what
you're doing is work or play
-------------------------------------
To achieve the impossible dream, try going to sleep.
-------------------------------------
Facts do not cease to exist because they are ignored.
-------------------------------------
Typing monkeys will write all Shakespeare's works in 200yrs.Will they
write all patents, too? :)
-------------------------------------
I finally figured out the only reason to be alive is to enjoy it.
|