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-17 21:21:16
Dear Ken,

Thank you for the prompt reply! I cannot use the "intersect" operator because it is XPath 2.0, but your suggestion made me look into how I can get the intersection of two node sets with XPath 1.0, and so I found out that there is the so-called Kaysian method for that, namely:

  $node_set_1[count(. | $node_set_2) = count($node_set_2)]

Hence, in my case the solution is:

   <xsl:variable name="node_set_1" select="following-sibling::foo"/>
   <xsl:variable name="node_set_2" select="following-sibling::*[not(self::foo)][1]/preceding-sibling::foo "/>    <xsl:copy-of select="$node_set_1[count(. | $node_set_2) = count($node_set_2)]"/>

Thanks again!
Wolfhart


On 17-02-21 23:12, G. Ken Holman g(_dot_)ken(_dot_)holman(_at_)gmail(_dot_)com 
wrote:
Would something like the following work for you?

  following-sibling::foo intersect
  following-sibling::*[not(self::foo)][1]/preceding-sibling::foo

. . . . . . . Ken

At 2021-02-18 01:32 +0000, Wolfhart Totschnig wolfhart(_dot_)totschnig(_at_)mail(_dot_)udp(_dot_)cl wrote:
Content-Transfer-Encoding: 8bit

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



--
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 |


--~----------------------------------------------------------------
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>