отличается в Xpath? - PullRequest
       45

отличается в Xpath?

45 голосов
/ 11 мая 2010

У меня есть этот XML-файл, из которого я хотел бы подсчитать количество пользователей, на которые есть ссылки. Но они могут появляться в нескольких категориях, и я бы хотел, чтобы эти дубликаты не учитывались.
В приведенном ниже примере запрос должен возвращать 3, а не 4. Есть ли способ в XPath сделать это? Пользователи вообще не сортируются.

<list>
  <group name='QA'>
    <user name='name1'>name1@email</user>
    <user name='name2'>name2@email</user>
  </group>
  <group name='DEV'>
    <user name='name3'>name3@email</user>
    <user name='name2'>name2@email</user>
  </group>
</list>

Ответы [ 6 ]

32 голосов
/ 11 мая 2010

Чистая XPath 1.0 - однострочная :

Использование :

count(/*/group/user[not(. = ../following-sibling::group/user)])

20 голосов
/ 11 мая 2010

используя пространство имен функций http://www.w3.org/2005/xpath-functions вы можете использовать

distinct-values(//list/group/user)

UPDATE:

В верхней части файла xsl / xslt у вас должен быть элемент таблицы стилей, сопоставьте приведенный выше URL с префиксом fn, как показано ниже ...

<xsl:stylesheet version="1.0"
 xmlns:fn="http://www.w3.org/2005/xpath-functions"
 >

тогда вы можете использовать

select="fn:distinct-values(//list/group/user)"

это предполагает, что вы делаете это в шаблонах, а не в каком-то объекте xpathdocument, в случае, если вам нужно использовать класс namespacemanager.

ссылки ...

XSLT: добавить пространство имен к корневому элементу

http://www.xqueryfunctions.com/xq/fn_distinct-values.html

http://msdn.microsoft.com/en-us/library/d6730bwt(VS.80).aspx

В противном случае попробовать ответ Дмитрия Новатчева.

3 голосов
/ 05 июня 2012

У меня есть лучший ответ

count(//user[not(. = following::user/.)])
1 голос
/ 11 мая 2010

Не уверен, что вы могли бы сделать это в XPath, но это легко сделать с помощью System.Linq:

string xml = "<list><group name='QA'><user name='name1'>name1@email</user><user name='name2'>name2@email</user></group><group name='DEV'><user name='name3'>name3@email</user><user name='name2'>name2@email</user></group></list>";
        XElement xe = XElement.Parse(xml);
        int distinctCount = xe.Elements().Elements().Select(n => n.Value).Distinct().Count();

В этом примере DifferentCount будет равен 3.

0 голосов
/ 30 августа 2018
count(//user[not(./@name = preceding::user/@name)])

Я думаю, что лучший способ - это нарисовать свои XML-данные на бумаге, чтобы увидеть, как их легко решить

0 голосов
/ 11 мая 2010

Вам нужно использовать две функции, подобные этой.

count(distinct-values(//list/group/user))

Сначала получите distinct значения, затем count их

...