Reputation: 1020
I have xml like follows,
<section>
<p id="ss_main">aa</p>
<p id="ss_main">bb</p>
<p id="main">cc</p>
<p id="main">dd</p>
<p id="main">ee</p>
<p id="ss_main">ff</p>
<p id="main">gg</p>
<p id="main">hh</p>
<p id="main">ii</p>
<p id="main">jj</p>
<p id="ss_main">xx</p>
<p id="ss_main">yy</p>
<p id="ss_main">zz</p>
</section>
you can see consecutive <p>
elements which attributes is staring from ss
. what I need is using xpath select the 1st <p>
element of every group which attribute is starting from ss
.
SO in above xml <p id="ss_main">aa</p>
, <p id="ss_main">ff</p>
, <p id="ss_main">xx</p>
should be selected.
I can write p[starts-with(@id,'ss')]
which select all <p>
element that id attr starting from ss
and p[starts-with(@id,'ss')][1]
which select only 1st <p>
element that id
starting from ss
.
Can anyone suggest me a method how can I select first <p>
element of each group that attr starting from ss
??
Upvotes: 0
Views: 527
Reputation: 12729
For this answer, I am assuming that you are using XPath 2.0 and that a different suffix (part of @id
content after the ss prefix) starts a new group.
This XPath 2.0 expression ...
p[ starts-with( @id, 'ss')]
[ not( @id eq preceding-sibling::p[1]/@id)]
... applied to document ...
<section>
<p id="ss_main">aa</p>
<p id="ss_main">bb</p>
<p id="main">cc</p>
<p id="main">dd</p>
<p id="main">ee</p>
<p id="ss_main">ff</p>
<p id="main">gg</p>
<p id="main">hh</p>
<p id="main">ii</p>
<p id="main">jj</p>
<p id="ss_main">xx</p>
<p id="ss_main">yy</p>
<p id="ss_main">zz</p>
</section>
... where the focus node is the section
element, resolves to ...
<p id="ss_main">aa</p>
<p id="ss_main">ff</p>
<p id="ss_main">xx</p>
Furthermore, when we apply the same expression to ...
<section>
<p id="ss_main">aa</p>
<p id="ss_DifferentGroup">bb</p>
<p id="main">cc</p>
<p id="main">dd</p>
<p id="main">ee</p>
<p id="ss_main">ff</p>
<p id="main">gg</p>
<p id="main">hh</p>
<p id="main">ii</p>
<p id="main">jj</p>
<p id="ss_main">xx</p>
<p id="ss_main">yy</p>
<p id="ss_main">zz</p>
</section>
... with the same focus node, we get ...
<p id="ss_main">aa</p>
<p id="ss_DifferentGroup">bb</p>
<p id="ss_main">ff</p>
<p id="ss_main">xx</p>
Upvotes: 1
Reputation: 89285
This is one possible XPath :
//p[starts-with(@id, 'ss')][not(preceding-sibling::p[1][starts-with(@id, 'ss')])]
brief explanation :
//p[starts-with(@id, 'ss')]
: find all p
elments having id
attribute starts with "ss"
...[not(preceding-sibling::p[1][starts-with(@id, 'ss')])]
: ... and not having direct preceding sibling element p
with the id
attribute starts with "ss"
Upvotes: 1