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

"Wolfhart Totschnig [email protected]" <[email protected]> Thu, 18 Feb 2021 03:21:17 -0000
Newsgroups gmane.text.xml.xsl.general.mulberrytech
Message-ID <[email protected]>
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 [email protected] 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 
> [email protected] 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/3329386
or by email: [email protected]
--~--