У меня возникли трудности с написанием шаблона, который генерирует пробную цепочку из структуры узла. До сих пор он работает неправильно, есть некоторая ошибка в моем мышлении о том, как он должен идти по пути item.
Рассмотрим следующую структуру страницы:
<!-- ===== SITE PAGE STRUCTURE ===================================== -->
<index>
<item section="home" id="index"></item>
<item section="service" id="index">
<item id="content-management-systems">
<item id="p1-1"/>
<item id="p1-2"/>
<item id="p1-3"/>
</item>
<item id="online-stores"></item>
<item id="search-engines-and-ir"></item>
<item id="web-applications"></item>
</item>
<item section="solutions" id="index">
<item id="document-clustering"></item>
</item>
<item section="company" id="index">
<item section="company" id="about"></item>
<item section="company" id="philosophy" ></item>
...
</item>
...
</item>
Этот индекс сайта представляет структуру сайта страниц контента xml в своей иерархии (считайте, что это меню). Он содержит разделы, представляющие разделы сайта, такие как дом, компания, услуги, решения и т. д. Эти разделы могут содержать подразделы. со страницами или просто с обычными страницами контента. Страница содержимого (ее XML-содержимое, такое как заголовок, текстовое содержимое и т. д.) идентифицируется атрибутом @id в дереве элементов. Атрибут @id в основном используется для получения содержимого всей страницы, которое будет преобразовано в html. Шаблон навигационной цепочки использует атрибут @id узла item для получения заголовка страницы (который будет отображаться в навигационной цепочке).
Я пытаюсь реализовать следующий шаблон, который обходит дерево, проверяя атрибут целевого раздела @section и атрибут целевой страницы @id в дереве. Я ожидаю, что он будет перемещаться по оси вниз до тех пор, пока целевой элемент item_target не будет найден путем сравнения атрибута предков @section и @id с $item_target каждого узла на этой оси.
Например: атрибут *$item_section=service* и идентификатор страницы *target item_target=p1-1* теперь должны рекурсивно «переходить» к ветке section «service» ( depth 1), проверьте, найдена ли целевая страница @id на этом уровне. В этом случае он не найден, поэтому он делает следующий рекурсивный вызов (через apply-templates) на следующий уровень узла item (в данном случае это будут content-management-systems< /strong>, там найдена целевая страница элемента p1-1, поэтому процесс трейла завершен:
Результат должен выглядеть следующим образом:
главная страница >> сервис >> системы управления контентом >> p1-1
Но, к сожалению, это работает неправильно, по крайней мере, не во всех случаях. Также, возможно, это может быть решено более легко. Я пытаюсь реализовать его как рекурсивный шаблон, который переходит от вершины (уровень 0) к целевой странице (узел элемента) в виде листа.
<!-- walk item path to generate a breadcrumb trail -->
<xsl:template name="breadcrumb">
<a>
<xsl:attribute name="href">
<xsl:text>/</xsl:text>
<xsl:value-of select="$req-lg"/>
<xsl:text>/home/index</xsl:text>
</xsl:attribute>
<xsl:value-of select="'Home'"/>
</a>
<xsl:apply-templates select="$content/site/index" mode="Item-Path">
<xsl:with-param name="item_section" select="'service'"/>
<xsl:with-param name="item_target" select="'search-engines-and-ir'"/>
<xsl:with-param name="depth" select="0"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="item" mode="Item-Path">
<xsl:param name="item_section" />
<xsl:param name="item_target" />
<xsl:param name="depth" />
<!--
depth=<xsl:value-of select="$depth"/>
count=<xsl:value-of select="count(./node())"/><br/>
-->
<xsl:variable name="cur-id" select="@id"/>
<xsl:variable name="cur-section" select="@section"/>
<xsl:choose>
<xsl:when test="@id=$item_target">
>>
<a>
<xsl:attribute name="href">
<xsl:text>/</xsl:text>
<!-- req-lg: global langauge variable -->
<xsl:value-of select="$req-lg"/>
<xsl:text>/</xsl:text>
<xsl:value-of select="$item_section"/>
<xsl:text>/</xsl:text>
<xsl:if test="$depth = 2">
<xsl:value-of select="../@id"/>
<xsl:text>/</xsl:text>
</xsl:if>
<xsl:value-of select="@id"/>
</xsl:attribute>
<xsl:value-of
select="$content/page[@id=$cur-id]/title"/>
</a>
</xsl:when>
<xsl:otherwise>
<xsl:if test="ancestor-or-self::item/@section = $item_section and count(./node()) > 0">
>>:
<a>
<xsl:attribute name="href">
<xsl:text>/</xsl:text>
<!-- req-lg: global langauge variable -->
<xsl:value-of select="$req-lg"/>
<xsl:text>/</xsl:text>
<xsl:value-of select="$item_section"/>
<xsl:text>/</xsl:text>
<xsl:if test="$depth = 2">
<xsl:value-of select="../@id"/>
<xsl:text>/</xsl:text>
</xsl:if>
<xsl:value-of select="@id"/>
</xsl:attribute>
<xsl:value-of
select="$content/page[@id=$cur-id and @section=$item_section]/title"/>
</a>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates select="item" mode="Item-Path">
<xsl:with-param name="item_section" select="$item_section"/>
<xsl:with-param name="item_target" select="$item_target"/>
<xsl:with-param name="depth" select="$depth + 1"/>
</xsl:apply-templates>
</xsl:template>
Так как жестко заданные параметры в шаблоне breadcrumb, target section = 'service' и target page = 'search-engines-and-ir', я ожидаю, что вывод будет выглядеть как
главная страница >> сервис >> поисковые системы и поисковые системы
Но выход
главная страница >> сервис >> системы управления контентом >> поисковые системы и IR
что явно не правильно.
Может ли кто-нибудь дать мне подсказку, как исправить эту проблему? Было бы даже элегантнее избежать этой проверки глубины, но пока я не могу придумать другого способа, я уверен, что есть более элегантное решение.
Я работаю с XSLT 1.0 (libxml через PHP5).
Надеюсь, мой вопрос достаточно ясен, если нет, спрашивайте :-) Заранее спасибо за помощь!
service >> search-engines-and-ir
? - person Sean B. Durkin   schedule 05.10.2012