xml - with - xslt condicional
¿Cómo contar valores distintos en un nodo? (4)
En XSLT 1.0 esto no es obvio, pero lo siguiente debería darle una idea del requisito:
count(//Artist_by_Country[not(Location_ID=preceding-sibling::Artist_by_Country/Location_ID)]/Location_ID)
Cuantos más elementos haya en su XML, más tiempo llevará esto, ya que verifica cada uno de los hermanos anteriores de cada elemento.
¿Cómo contar valores distintos en un nodo en XSLT?
Ejemplo: Quiero contar el número de países existentes en los nodos País, en este caso, sería 3.
<Artists_by_Countries>
<Artist_by_Country>
<Location_ID>62</Location_ID>
<Artist_ID>212</Artist_ID>
<Country>Argentina</Country>
</Artist_by_Country>
<Artist_by_Country>
<Location_ID>4</Location_ID>
<Artist_ID>108</Artist_ID>
<Country>Australia</Country>
</Artist_by_Country>
<Artist_by_Country>
<Location_ID>4</Location_ID>
<Artist_ID>111</Artist_ID>
<Country>Australia</Country>
</Artist_by_Country>
<Artist_by_Country>
<Location_ID>12</Location_ID>
<Artist_ID>78</Artist_ID>
<Country>Germany</Country>
</Artist_by_Country>
</Artists_by_Countries>
Pruebe algo como esto:
count(//Country[not(following::Country/text() = text())])
"Dame el recuento de todos los nodos de País sin un País siguiente con el texto correspondiente"
El bit interesante de esa expresión, IMO, es el siguiente eje.
Probablemente también puedas eliminar el primero /text()
y reemplazar el segundo con .
Si tiene control de la generación xml en la primera ocurrencia de un país, puede agregar un atributo al nodo país, como distinct = ''true'', marcar el país como "used" y no agregar posteriormente el atributo distinct si se encuentra con ese atributo país de nuevo.
Entonces podrías hacer
<xsl:for-each select="Artists_by_Countries/Artist_by_Country/Country[@distinct=''true'']" />
Si tiene un documento grande, probablemente desee utilizar el "Método de Muenchian", que generalmente se utiliza para agrupar, para identificar los distintos nodos. Declare una clave que indexa las cosas que desea contar por los valores que son distintos:
<xsl:key name="artists-by-country" match="Artist_by_Country" use="Country" />
Luego puede obtener los elementos <Artist_by_Country>
que tienen distintos países utilizando:
/Artists_by_Countries
/Artist_by_Country
[generate-id(.) =
generate-id(key(''artists-by-country'', Country)[1])]
y puede contarlos envolviendo eso en una llamada a la función count()
.
Por supuesto, en XSLT 2.0, es tan simple como
count(distinct-values(/Artists_by_Countries/Artist_by_Country/Country))