Subject: Re: [xsl] with XPath 1.0, select all following sibling elements of name "foo" up to the first non-"foo" element From: "G. Ken Holman g.ken.holman@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Fri, 19 Feb 2021 02:24:35 -0000 |
Just eyeballing this, Dmitry, I'm not convinced it would work if Wolfhart was sitting at a <foo> at the time he made his request, in which case the <foo> he was at would incorrectly be included.
Granted the original requirement is underspecified in this regard, so perhaps my observation is irrelevant. I'm not trying to nit-pick but I discounted the use of keys because of the arbitrary starting point for evaluation.
Also the use= needs a "[1]" predicate to ensure the correct cardinality for generate-id() in the general case where there are multiple following siblings that are not <foo>.
I'm usually successful with keys when not having to deal with the current context.
Here is a short and efficient XSLT 1.0 solution using keys:Transform">
<xsl:stylesheet version="1.0" xmlns:xsl="<http://www.w3.org/1999/XSL/Transform>http://www.w3.org/1999/XSL/
result:B <xsl:output omit-xml-declaration="yes" indent="yes"/> B <xsl:key name="kPrecedingFoo" match="foo" use="generate-id(following-sibling::*[not(self::foo)])"/> B B <xsl:template match="/*/*[1]"> B B <xsl:copy-of select="key('kPrecedingFoo', generate-id(../*[not(self::foo)][1]))"/> B </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
errytech.com>
<t> B <!-- <bar/> --> B <foo ind="1"/> B <foo ind="2"/> B <!-- <bar/> --> B <foo ind="3"/> </t>
Cheers, Dimitre
On Wed, Feb 17, 2021 at 5:32 PM Wolfhart Totschnig <mailto:wolfhart.totschnig@xxxxxxxxxxx>wolfhart.totschnig@xxxxxxxxxxx <<mailto:xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>xsl-list-service@xxxxxxxxxx
::source][preceding-sibling::current()]"/>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:
B B B B B B B B B B <xsl:choose> B B B B B B B B B B B B B <xsl:when test="not(following-sibling::*[not(self::foo)])"> B B B B B B B B B B B B B B B B <xsl:value-of select="following-sibling::*"/> B B B B B B B B B B B B B </xsl:when> B B B B B B B B B B B B B <xsl:otherwise> B B B B B B B B B B B B B B B B <xsl:value-of select="following-sibling::*[not(self::source)][1]/preceding-sibling::*[self
B B B B B B B B B B B B B </xsl:otherwise> B B B B B B B B B B </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. B <http://www.mulberrytech.com/xsl/xsl-list>XSL-List info and archive <http://lists.mulberrytech.com/unsub/xsl-list/96802>EasyUnsubscribe (<>by email)
-- Contact info, blog, articles, etc. http://www.CraneSoftwrights.com/s/ | Check our site for free XML, XSLT, XSL-FO and UBL developer resources | Streaming hands-on XSLT/XPath 2 training class @US$125 (5 hours free) | Essays (UBL, XML, etc.) http://www.linkedin.com/today/author/gkholman |
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] with XPath 1.0, select al, Dimitre Novatchev dn | Thread | Re: [xsl] with XPath 1.0, select al, Dimitre Novatchev dn |
Re: [xsl] with XPath 1.0, select al, Dimitre Novatchev dn | Date | Re: [xsl] with XPath 1.0, select al, Dimitre Novatchev dn |
Month |