XPath Zaznacz wszystkie elementy pomiędzy dwoma określonymi elementami
Mam następujący xml:
<doc>
<divider />
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<divider />
<p>text</p>
<p>text</p>
<divider />
<p>text</p>
<divider />
</doc>
Chcę zaznaczyć wszystkie węzły p po pierwszym elemencie dzielącym aż do następnego wystąpienia elementu dzielącego. Próbowałem z następującym xpath:
//divider[1]/following-sibling::p[following::divider]
Ale problem polega na tym, że wybiera wszystkie elementy p przed ostatnim elementem dzielącym. Nie jestem pewien jak to zrobić używając xpath 1.
4 answers
Ta sama koncepcja co bytebuster, ale inna xpath:
/*/p[count(preceding-sibling::divider)=1]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-02 04:50:36
Oto ogólne wyrażenie XPath :
/*/divider[$k]
/following-sibling::p
[count(.|/*/divider[$k+1]/preceding-sibling::p)
=
count(/*/divider[$k+1]/preceding-sibling::p)
]
Jeśli zamienisz $k
na 1
, wybierane są dokładnie żądane p
węzły.
Jeśli zamienisz $k
na 2
wtedy wszystkie p
elementy między 2. a 3. divider
,..., itd.
Wyjaśnienie :
Jest to proste zastosowanie Kayessian formuły XPath 1.0 Dla przecięcia zestawu węzłów:
$ns1[count(.|$ns2) = count($ns2)]
Wybiera wszystkie węzły, które należą zarówno do nodesetów $ns1
jak i $ns2
.
W tym konkretnym przypadku zamieniamy $ns1
na:
/*/divider[$k]/following-sibling::p
I zamieniamy $ns2
na:
/*/divider[$k+1]/preceding-sibling::p
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-02 05:09:42
Myślę, że jest o wiele prostsze i prawdopodobnie szybsze rozwiązanie: chcesz, aby wszystkie poprzednie rodzeństwo drugiego dzielnika miało przynajmniej jeden poprzedni dzielnik rodzeństwa:
/doc/divider[2]/preceding-sibling::p[preceding-sibling::divider]
Robi się to trochę bardziej złożone, oczywiście, jeśli chcesz znaleźć paras między drugim i trzecim dzielnikiem: wtedy chcesz coś bardziej podobnego do rozwiązania Daniela Haleya.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-05 23:36:22
A co z zaznaczeniem WSZYSTKICH p
mających dokładnie Jeden element divider
jako preceding-sibling
?
//doc/p[preceding-sibling::divider[1] and not (preceding-sibling::divider[2])]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-02 04:21:40