[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: with XPath 1.0, select all following sibling eleme
Here is a short and efficient XSLT 1.0 solution using keys: <xsl:stylesheet version="1.0" xmlns:xsl=" http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:key name="kPrecedingFoo" match="foo" use="generate-id(following-sibling::*[not(self::foo)])"/> <xsl:template match="/*/*[1]"> <xsl:copy-of select="key('kPrecedingFoo', generate-id(../*[not(self::foo)][1]))"/> </xsl:template> </xsl:stylesheet> Applying this transformation on variations of the following XML document (try uncommenting different subsets of the commented elements) produces always the wanted result: <t> <!-- <bar/> --> <foo ind="1"/> <foo ind="2"/> <!-- <bar/> --> <foo ind="3"/> </t> Cheers, Dimitre On Wed, Feb 17, 2021 at 5:32 PM Wolfhart Totschnig wolfhart.totschnig@xxxxxxxxxxx <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote: > Dear list, > > I am facing an XPath problem for which I cannot find the solution. I > want to select all following sibling elements of name "foo" up to the > first non-"foo" element. So, in the following case, the first two <foo> > elements should be selected: > > <foo/> > <foo/> > <bar/> > <foo/> > > In the following case, all three <foo> elements should be selected: > > <foo/> > <foo/> > <foo/> > > And in the following case, nothing should be selected: > > <bar/> > <foo/> > <foo/> > > I came up with the following non-working approach: > > <xsl:choose> > <xsl:when > test="not(following-sibling::*[not(self::foo)])"> > <xsl:value-of select="following-sibling::*"/> > </xsl:when> > <xsl:otherwise> > <xsl:value-of > > select="following-sibling::*[not(self::source)][1]/preceding-sibling::*[self::source][preceding-sibling::current()]"/> > </xsl:otherwise> > </xsl:choose> > > That is, test whether there are non-"foo" following siblings. If there > are none, take all following siblings. If there are, go forward to the > first non-"foo" sibling, and from there go backwards, taking all the > "foo" siblings up to the current node. > > But this does not work. Apparently, the expression > "preceding-sibling::current()" is not a valid construct. So what is the > correct way to do what I have in mind (or a simpler solution, if there > is one). Please note that this stylesheet needs to be executed by a web > browser, and so the solution has to remain within XPath 1.0. > > Thanks in advance for your help! > Wolfhart > > > -- 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? :) ------------------------------------- Sanity is madness put to good use. ------------------------------------- I finally figured out the only reason to be alive is to enjoy it.
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|