Причина, по которой вы получаете два элемента ul
, заключается в том, что ваш шаблон, генерирующий элемент ul
, соответствует элементам с именем WideTeaserElement
, из которых у вас есть два.
Я думаю, что я могу видеть, гдемы думали об этом - предполагали ли вы, что этот шаблон будет обрабатывать все WideTeaserElement
с за одну операцию, которую затем вы можете повторить с помощью «для каждого из них»?Вместо этого шаблон вызывается отдельно для каждого вхождения узла WideTeaserElement
, а затем «перебирает» его единственное вхождение.
Я согласен с Норманом в том, что for-each
редко является лучшим вариантом, ноЯ могу подумать о двух причинах, по которым вы могли бы его использовать.
- Удобочитаемость;если объем обработки для каждой итерации относительно мал, это может облегчить чтение вашей таблицы стилей, если код, обрабатывающий ее, находится в родительском шаблоне.
Для (очень упрощенного) примера япредпочел бы
<xsl:template match="mylist">
<xsl:element name="ul">
<xsl:for-each select="listitem">
<xsl:element name="li">
<xsl:value-of select="." />
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
вместо
<xsl:template match="mylist">
<xsl:element name="ul">
<xsl:apply-templates select="listitem" />
</xsl:element>
</xsl:template>
<xsl:template match="listitem">
<xsl:element name="li">
<xsl:value-of select="." />
</xsl:element>
</xsl:template>
, если бы шаблон mylist
на самом деле содержал намного больше кода, и последнее решение означало бы необходимость прокручивать мой код вниз, чтобы увидетькак обрабатывается listitem
Это субъективно, хотя, некоторые могут предпочесть последнее решение всегда.Лично я обычно нахожу, что большинство шаблонов достаточно велики, чтобы разбивать их лучше для удобства чтения, но в меньших это не всегда так.
- Там, где вы не хотите, чтобы узлы повторялисьбудет рассматриваться как шаблон.В приведенном выше примере последнее решение будет преобразовывать ВСЕ
listitem
теги, а не только те, которые находятся внутри тега «mylist».Конечно, его можно ограничить, изменив совпадение на listitem[parent::mylist]
, но часто for-each
просто точнее, чем создание нескольких шаблонов для одного и того же имени элемента на основе родословной.
Вообще говоря, хотяобычно вы можете заменить
<xsl:template match="foo">
<xsl:for-each select="bar">
..
</xsl:for-each>
</xsl:template>
на
<xsl:template match="foo">
<xsl:apply-templates select="bar" />
</xsl:template>
<xsl:template match="bar">
..
</xsl:template>
в любом документе, где элемент bar
всегда имеет элемент foo
в качестве родительского.