Как подсчитать различные значения в узле в XSLT?
Пример: я хочу подсчитать количество существующих стран в узлах страны, в данном случае это будет 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>
Если у Вас есть большой документ, Вы, вероятно, хотите использовать "Метод Muenchian", который обычно используется для группировки, для идентификации отличных узлов. Объявите ключ, который индексирует вещи, которые Вы хотите считать значениями, которые отличны:
<xsl:key name="artists-by-country" match="Artist_by_Country" use="Country" />
Тогда можно добраться <Artist_by_Country>
элементы, которые имеют отличное использование стран:
/Artists_by_Countries
/Artist_by_Country
[generate-id(.) =
generate-id(key('artists-by-country', Country)[1])]
и можно считать их путем обертывания этого в вызов к эти count()
функция.
, Конечно, в XSLT 2.0, это столь же просто как
count(distinct-values(/Artists_by_Countries/Artist_by_Country/Country))
Попробуйте что-то вроде этого:
count(//Country[not(following::Country/text() = text())])
"Дают мне количество всех узлов Страны без следующей Страны с совпавшим текстом"
, интересный бит того выражения, IMO, после ось.
Вы могли, вероятно, также удалить первое /text()
и заменить второе .
Если Вы имеете контроль над xml поколением на первом вхождении страны, Вы могли бы добавить, что атрибут к узлу страны, такому как отличный ='true' отмечает страну, как "используется" и не впоследствии добавляет отличный атрибут при случайной встрече с той страной снова.
Вы могли тогда сделать
<xsl:for-each select="Artists_by_Countries/Artist_by_Country/Country[@distinct='true']" />
В XSLT 1.0 это не очевидно, но следующее должно дать Вам общее представление о требовании:
count(//Artist_by_Country[not(Location_ID=preceding-sibling::Artist_by_Country/Location_ID)]/Location_ID)
, Чем больше элементов в Вашем XML, тем дольше это берет, поскольку он проверяет каждый предыдущий одноуровневый элемент каждого элемента.