xsl-list
[Top] [All Lists]

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

2021-02-18 12:43:11
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(_at_)wendellpiez(_dot_)com 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(_dot_)totschnig(_at_)mail(_dot_)udp(_dot_)cl <mailto:wolfhart(_dot_)totschnig(_at_)mail(_dot_)udp(_dot_)cl> <xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com <mailto:xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com>> 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. <http://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/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--
<Prev in Thread] Current Thread [Next in Thread>