J'ai ce fichier XML, à partir duquel j'aimerais compter le nombre d'utilisateurs référencés. Mais ils peuvent apparaître dans plus d'une catégorie et j'aimerais que ces doublons ne soient pas pris en compte.
Dans l'exemple ci-dessous, la requête devrait renvoyer 3 et non 4. Existe-t-il un moyen de le faire dans XPath? Les utilisateurs ne sont pas triés du tout.
<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>
en utilisant les fonctions namespace http://www.w3.org/2005/xpath-functions vous pouvez utiliser
distinct-values(//list/group/user)
METTRE À JOUR:
En haut de votre fichier xsl/xslt, vous devriez avoir un élément de feuille de style, mappez l'URL ci-dessus sur le préfixe fn
comme ci-dessous ...
<xsl:stylesheet version="1.0"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
>
alors vous pouvez utiliser
select="fn:distinct-values(//list/group/user)"
cela supposerait que vous le fassiez dans des modèles et non dans un objet xpathdocument dans lequel vous devez utiliser une classe namespacemanager.
liens...
XSLT: Ajouter un espace de noms à l'élément racine
http://www.xqueryfunctions.com/xq/fn_distinct-values.html
http://msdn.Microsoft.com/en-us/library/d6730bwt(VS.80).aspx
Sinon essayez la réponse de Dimitre Novatchev.
J'ai une meilleure réponse
count(//user[not(. = following::user/.)])
Vous n'êtes pas sûr de pouvoir le faire dans XPath, mais vous pouvez le faire facilement avec 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();
Dans cet exemple, distinctCount sera égal à 3.
Vous devrez utiliser deux fonctions comme celle-ci.
count(distinct-values(//list/group/user))
Commencez par obtenir les valeurs distinct
, puis count
count(//user[not(./@name = preceding::user/@name)])
Je pense que le meilleur moyen est d'essayer de dessiner vos données XML sur papier pour voir comment vous pouvez les résoudre facilement