Как посчитать разные значения в узле?

Как подсчитать различные значения в узле в 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>
13
задан 17.05.2020, 06:36

4 ответа

Если у Вас есть большой документ, Вы, вероятно, хотите использовать "Метод 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))
26
ответ дан 17.05.2020, 06:38

Попробуйте что-то вроде этого:

count(//Country[not(following::Country/text() = text())])

"Дают мне количество всех узлов Страны без следующей Страны с совпавшим текстом"

, интересный бит того выражения, IMO, после ось.

Вы могли, вероятно, также удалить первое /text() и заменить второе .

5
ответ дан 17.05.2020, 06:36
  • 1
    Это будет только работать, если узлы будут отсортированы и т.п., значения Страны поэтому последовательны. – dacracot 17.05.2020, 06:37
  • 2
    Нет, это будет всегда работать. следующее:: работы над всем документом, если существует КАКАЯ-ЛИБО страна после той контекста, которая имеет то же значение, тот узел, не будут считаться. – Chris Marasti-Georg 17.05.2020, 06:37

Если Вы имеете контроль над xml поколением на первом вхождении страны, Вы могли бы добавить, что атрибут к узлу страны, такому как отличный ='true' отмечает страну, как "используется" и не впоследствии добавляет отличный атрибут при случайной встрече с той страной снова.

Вы могли тогда сделать

<xsl:for-each select="Artists_by_Countries/Artist_by_Country/Country[@distinct='true']" />
0
ответ дан 17.05.2020, 06:37

В XSLT 1.0 это не очевидно, но следующее должно дать Вам общее представление о требовании:

count(//Artist_by_Country[not(Location_ID=preceding-sibling::Artist_by_Country/Location_ID)]/Location_ID)

, Чем больше элементов в Вашем XML, тем дольше это берет, поскольку он проверяет каждый предыдущий одноуровневый элемент каждого элемента.

6
ответ дан 17.05.2020, 06:38
  • 1
    Не уверенный в производительности, но для XSLT 1.0, это походит на более чистое решение, чем требование < xsl:key/> элемент в вершине проголосовал за решение. – Jay Stevens 17.05.2020, 06:38
  • 2
    Обычно существует по крайней мере два способа освежевать кошку в XSLT - и который является лучшим, будет зависеть от Ваших конкретных обстоятельств. xsl:key может быть очень быстрым в хорошем процессоре на больших документах, выдерживают сравнение с моим методом выше, я подозреваю. – samjudson 17.05.2020, 06:39

Теги

Похожие вопросы