Если элемент в генеральной совокупности не соответствует group-by в группе для каждой-группы, может ли он быть назначен группе с пустым ключом current-group-key ()?

Итак, у меня есть такие данные:

<Root>
 <Item id="1" group="foo" />
 <Item id="2" group="bar" />
 <Item id="3" />
</Root>

И шаблонная инструкция вроде:

<xsl:for-each-group select="Root" group-by="@group" />

Казалось бы, я получаю группы только для foo и bar. (Почему? Я ожидал, что смогу получить третью группу с current-group-key() = '').

Я действительно хочу эту 3-ю группу. Какие у меня есть варианты?

спасибо, Дэвид.


person David Bullock    schedule 28.10.2012    source источник
comment
использование group-by="concat('',@group)" дает мне 3-ю группу. Я до сих пор не понимаю, почему group-by ведет себя именно так.   -  person David Bullock    schedule 28.10.2012


Ответы (2)


Спецификация XSLT 2.0 http://www.w3.org/TR/xslt20/#xsl-for-each-group говорит следующее о group-by:

Если атрибут group-by присутствует, элементы в генеральной совокупности проверяются в порядке совокупности. Для каждого элемента J выражение в атрибуте группировки оценивается для создания последовательности из нуля или более значений ключа группировки. Для каждого из этих ключей группировки, если уже существует группа, созданная для хранения элементов, имеющих это значение ключа группировки, J добавляется в эту группу; в противном случае для элементов с этим значением ключа группировки создается новая группа, и J становится ее первым членом.

Таким образом, элемент в генеральной совокупности может быть отнесен к нулю, одной или нескольким группам.

Итак, в вашем случае, когда group-by выражение @group оценивается для третьего Item элемента, оно оценивается как пустая последовательность, и, таким образом, не найден ключ группировки, вызывающий добавление элемента в какую-либо группу. Таким образом, третий Item не принадлежит ни к какой группе.

person Martin Honnen    schedule 28.10.2012
comment
Ага! Я прочитал этот абзац по крайней мере один раз перед публикацией, но до сих пор в нем не было смысла. Спасибо. - person David Bullock; 29.10.2012

Мартин дал хорошее объяснение.

Если то, что вы хотите, разрешено, то элементы, у которых вообще нет атрибута group, будут в той же группе, что и элементы, у которых есть атрибут group='' - и это неточно.

Самое простое решение - указать в атрибуте group-by, что наличие атрибута group не имеет значения.

Самый простой способ сделать это:

<xsl:for-each-group select="Root/*" group-by="string(@group)">

Вот полное преобразование:

<xsl:stylesheet version="2.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>

 <xsl:template match="/">
  <xsl:for-each-group select="Root/*" group-by="string(@group)">
   "<xsl:sequence select="string(@group)"/>"
  </xsl:for-each-group>
 </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется к предоставленному XML-документу:

<Root>
    <Item id="1" group="foo" />
    <Item id="2" group="bar" />
    <Item id="3" />
</Root>

желаемый результат получен:

   "foo"

   "bar"

   ""
person Dimitre Novatchev    schedule 28.10.2012
comment
Это помогло закрепить это практическим примером. Спасибо. - person David Bullock; 29.10.2012