Re: [xsl] with XPath 1.0, select all following sibling elements of name "foo" up to the first non-"foo" element

Subject: Re: [xsl] with XPath 1.0, select all following sibling elements of name "foo" up to the first non-"foo" element
From: "Wendell Piez wapiez@xxxxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 18 Feb 2021 21:05:22 -0000
Hi again,

Is it worth adding that in 2.0 this could be (following-sibling::boo)
except ((following-sibling::* except
following-sibling::boo)/following-sibling::boo)?

Untested ...

Cheers, Wendell


On Thu, Feb 18, 2021 at 4:00 PM Wendell Piez <wapiez@xxxxxxxxxxxxxxx> wrote:

> Wolfhart,
>
> What Ken says is correct, name() is not namespace-safe. Here we hit a wall
> in XPath 1.0. In 2.0 there is a function node-name() to help with that.
>
> As for the notion of 'preceding-sibling::current()' that fails because
> current() is not an XPath 1.0 node test, so it does not parse as a path
> expression. (It is an XSLT 1.0 function.)
>
> The self::... business is interesting. Generally this is preferred to
> using name tests, for sure. (Because, as Ken would surely hasten to point
> out, it is namespace safe.) However, when it is not the axis (self::) but
> the node test (the ... i.e. the name test in this case) that needs to be
> dynamic, it isn't much help.
>
> However, if you know in advance you are looking for boo elements you can
> simultaneously address any potential namespace problems:
>
> <xsl:variable name="followers" select="following-sibling::boo"/>
> <xsl:variable name="interlopers" select="following-sibling::*[not(self::boo)]
> | following-sibling::* [not(self::boo)]/following-sibling::*"/>
> <xsl:variable name="invited" select=". | $followers[not(count(.|$
> interlopers)=count($interlopers))]"/>
>
> Cheers, Wendell
>
>
> On Thu, Feb 18, 2021 at 1:43 PM Wolfhart Totschnig
> wolfhart.totschnig@xxxxxxxxxxx <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
> wrote:
>
>> Hello again,
>>
>> Thank you, Wendell!
>>
>> The proposed solutions leave me with two questions:
>>
>>
>> 1) Is there a way to do what I originally had in mind, i.e., go forward
>> to the first non-"foo" sibling and from there go backwards, taking all the
>> "foo" siblings up to the current node? Asked differently, can the
>> following XPath expression be fixed?
>>
>>
>> following-sibling::*[not(self::source)][1]/preceding-sibling::*[self::source][preceding-sibling::current()]
>>
>> Specifically, can "preceding-sibling::current()" be fixed?
>>
>>
>> 2) Liam's and Wendell's proposals involve the expression [name()=...],
>> whereas I have used [self:: ...]. Are these strictly equivalent, or is
>> there a reason to prefer the one over the other?
>>
>>
>> Thanks again for your help!
>> Wolfhart
>>
>>
>> On 18-02-21 13:06, Wendell Piez wapiez@xxxxxxxxxxxxxxx wrote:
>>
>> Hi,
>>
>> With a sequence of variable declarations:
>>
>> <xsl:variable name="name" select="name()"/>
>> <xsl:variable name="followers"
>> select="following-sibling::*[name()=$name]"/>
>> <xsl:variable name="interlopers"
>> select="following-sibling::*[not(name()=$name)] |
>> following-sibling::*[not(name()=$name)]/following-sibling::*"/>
>> <xsl:variable name="invited" select=". |
>> $followers[not(count(.|$interlopers)=count($interlopers))]"/>
>>
>> Note: untested.
>>
>> Good luck,
>> Wendell
>>
>>
>> On Wed, Feb 17, 2021 at 8: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
>>>
>>>
>>>
>>
>> --
>> ...Wendell Piez... ...wendell -at- nist -dot- gov...
>> ...wendellpiez.com... ...pellucidliterature.org... ...pausepress.org...
>> ...github.com/wendellpiez... ...gitlab.coko.foundation/wendell...
>> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
>> EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/2652055> (by
>> email)
>>
>>
>> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
>> EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/174322> (by
>> email <>)
>>
>
>
> --
> ...Wendell Piez... ...wendell -at- nist -dot- gov...
> ...wendellpiez.com... ...pellucidliterature.org... ...pausepress.org...
> ...github.com/wendellpiez... ...gitlab.coko.foundation/wendell...
>


-- 
...Wendell Piez... ...wendell -at- nist -dot- gov...
...wendellpiez.com... ...pellucidliterature.org... ...pausepress.org...
...github.com/wendellpiez... ...gitlab.coko.foundation/wendell...

Current Thread