2010-05-11 19 views
43

我有这个XML文件,我想从中计算引用的用户数量。但是它们可以出现在多个类别中,我希望不要将这些重复项目考虑在内。
在下面的例子中,查询应该返回3而不是4.在XPath中有没有办法做到这一点?用户根本没有排序。在Xpath中不同?

<list> 
    <group name='QA'> 
    <user name='name1'>[email protected]</user> 
    <user name='name2'>[email protected]</user> 
    </group> 
    <group name='DEV'> 
    <user name='name3'>[email protected]</user> 
    <user name='name2'>[email protected]</user> 
    </group> 
</list> 
+1

很好的问题(+1)。查看我的答案,获取纯XPath 1.0单线解决方案。 :) – 2010-05-11 16:59:59

回答

30

一个纯粹的XPath 1.0 - 一个班轮

使用

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

+0

这只会在用户名无法使用时才起作用?如果是这种情况(它已经晚了,我一直在喝......),你可以添加[(不((。= ../following-sibling::group/user))和(not(。= ../preceading -sibling :: group/user))] – gingerbreadboy 2010-05-11 22:21:18

+0

但它是对的+1 – gingerbreadboy 2010-05-11 22:36:05

+0

@runrunraygun为什么测试与所有东西都不相等?测试没有相同的后续兄弟姐妹只需从一组相等的值中取一个值 - 正是想要的。 :)感谢您的赞赏。 – 2010-05-11 23:09:41

0

您将需要使用这样的两个功能。

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

首先得到了distinct值,然后count他们

+1

好,但你有没有测试过?请更正 - 这只是一个“小问题”问题。 :) – 2010-05-11 17:01:32

+0

是的,这个作品 – 2010-05-11 17:15:26

+2

卖家:如果“这有效”,那么你有一个不兼容的XPath 2.0引擎!显然,你根本没有测试你提出的XPath表达式! * Hint1 *:在XPath中没有'COUNT()'函数。 *提示2 *:XPath区分大小写。 – 2010-05-12 02:40:23

13

使用功能命名空间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对象这样做,而不是inwhich情况下,你需要使用一个namespacemanager类。

链接...

XSLT: Add namespace to root element

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

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

否则尝试Dimitre Novatchev的答案。

+0

好的,让我们来处理命名空间。呃,更好地刺自己。 – Antoine 2010-05-11 16:36:34

+2

'distinct-values()'函数仅在XPath 2.0中实现,这意味着仅在XSLT 2.0中。您的答案中的代码在XSLT 1.0中不起作用。请改正。 – 2010-05-12 02:42:31

+1

@Dimitre:OP没有指定XSLT 1.0,所以我认为说“please,correct”有点粗鲁。这个答案已经是正确的了。 – 2012-04-25 13:03:38

1

不知道,如果你能做到这一点在XPath的,但它可以很容易地使用System.Linq的完成:

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

在这个例子中,distinctCount将等于3

+0

听起来没错,但我正在使用.net框架的旧版本,并且无法轻松升级生产应用程序。 – Antoine 2010-05-11 16:34:56

+0

啊,对不起!我没有意识到你不在.Net 3.5上。 – JSprang 2010-05-11 16:40:28

3

我有更好的回答

count(//user[not(. = following::user/.)])