I have this XML file from which I would like to count the number of users to which it refers. But they can appear in more than one category, and I would like these duplicates not to be taken into account.In the example below, the query should return 3, not 4. Is there a way in XPath for this? Users are not sorted at all.
<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>
Pure XPath 1.0 - Single Line :
Using
count(/*/group/user[not(. = ../following-sibling::group/user)])
using the function namespace http://www.w3.org/2005/xpath-functions , you can use
distinct-values(//list/group/user)
UPDATE:
There should be a stylesheet element at the top of your xsl / xslt file, map the url above with the fn prefix, as shown below ...
fn
<xsl:stylesheet version="1.0" xmlns:fn="http://www.w3.org/2005/xpath-functions" >
then you can use
select="fn:distinct-values(//list/group/user)"
this suggests that you do this in templates, and not in any xpathdocument object in which you need to use the namespacemanager class.
links ...
XSLT: add a namespace to the root element
http://www.xqueryfunctions.com/xq/fn_distinct-values.html
http://msdn.microsoft.com/en-us/library/d6730bwt(VS.80).aspx
Otherwise, try to answer Dimitry Novachev.
I have a better answer
count(//user[not(. = following::user/.)])
Not sure if you can do this in XPath, but it can be done easily with 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();
In this example, distinctCount will be 3.
You will need to use two functions like this.
count(distinct-values(//list/group/user))
First get distinct values, then count them
distinct
count