Получать элементы, ссылающиеся ровно на два других элемента в одном выражении XPath - PullRequest
2 голосов
/ 12 ноября 2010

Мне нужно получить набор узлов, содержащий элементы, которые относятся ровно к двум другим элементам.Я не могу понять, как это сделать в одном выражении XPath.

Мой (упрощенный) исходный XML выглядит следующим образом:

<group>
   <id>1337</id>
</group>
<group>
   <id>1338</id>
</group>
<member>
   <id>31415</id>
   <groupId>1337</groupId>
</member>
<member>
   <id>31416</id>
   <groupId>1337</groupId>
</member>
<member>
   <id>31417</id
   <groupId>1338</groupId>
</member>

Теперь я хочу выбрать все <group> узлы, которые относятся ровно к двум <member> с, что должно привести к возврату группы только с id = 1337.Я попробовал следующее ...

<xsl:variable name="groupsWithTwoMembers" select="group[count(../member[id=??]) = 2]"/>

... и, очевидно, в "??"Мне нужно вставить groupId группы, которую я выбрал в начале выражения XPath, но я не могу придумать, как добраться до этого groupId.Может ли кто-нибудь думать об этом?Спасибо!

Ответы [ 4 ]

2 голосов
/ 12 ноября 2010

Проблема заключается в том, что предикаты фильтруют предыдущие выбранные узлы с каждый из этих узлов в качестве контекста . Итак, вам нужно вытащить вне контекста ссылку.

Это можно сделать с помощью ссылки на переменную / параметр или current() (в результате получается контекстный узел для всей инструкции XSLT).

Также, в этом случае, имея перекрестные ссылки, лучше использовать ключи:

<xsl:key name="kMemberByGroupId" match="member" use="groupId"/>  
...
<xsl:variable name="groupsWithTwoMembers" 
              select="group[count(key('kMemberByGroupId',id)) = 2]"/>
1 голос
/ 12 ноября 2010

XPath2.0 :

$p/group[count(index-of($p/member/groupId, id)) eq 2]

, где $p - родительский элемент предоставленного фрагмента XML.

0 голосов
/ 12 ноября 2010

Вы должны посмотреть на разницу между текущим узлом и узлом контекста.Они обычно одинаковы, но при работе с предикатами контекстный узел (часто обозначаемый знаком.) Совпадает с узлом, с которым вы работаете.В этой ситуации вы должны использовать current () для доступа к текущему узлу, а не к контекстному узлу.

0 голосов
/ 12 ноября 2010

В XPath 1.0 это невозможно. В XPath 2.0 вы можете делать следующее (не проверено):

for $a in fn:distinct-values(//group/id) 
  if count(../../member[@id = $a]) = 2 then return $a
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...