Соответствие различным дескрипторам узла для получения значения узла с помощью XSLT
XSLT доступно 1.0.
Я работаю на двухязыковом сайте в CMS на основе XML (Symphony CMS), и мне нужно заменить английскую версию названия категории французской версией.
Это мой исходный XML.
<data>
<our-news-categories-for-list-fr>
<entry id="118">
<title-fr handle="technology">Technologie</title-fr>
</entry>
<entry id="117">
<title-fr handle="healthcare">Santé</title-fr>
</entry>
</our-news-categories-for-list-fr>
<our-news-article-fr>
<entry id="100">
<categories>
<item id="117" handle="healthcare" section-handle="our-news-categories" section-name="Our News categories">Healthcare</item>
<item id="118" handle="technology" section-handle="our-news-categories" section-name="Our News categories">Technology</item>
</categories>
<main-text-fr mode="formatted"><p>Blah blah</p></main-text-fr>
</entry>
</our-news-article-fr>
</data>
Это часть XSLT, которую я сейчас использую для французской версии.
<xsl:template match="data">
<xsl:apply-templates select="our-news-article-fr/entry"/>
</xsl:template>
<xsl:template match="our-news-article-fr/entry">
<xsl:if test="categories/item">
<p class="category">In:</p>
<ul class="category">
<xsl:for-each select="categories/item">
<li><a href="{/data/params/root}/{/data/params/root-page}/our-news/categorie/{@handle}/"><xsl:value-of select="."/></a></li>
</xsl:for-each>
</ul>
</xsl:if>
</xsl:template match>
Проблема: видимый текст якоря (<xsl:value-of select="."/>
) дает английскую версию названия категории.
Дескрипторы следующих узлов совпадают (все дескрипторы на английском языке), и поэтому я думаю, что я должен быть в состоянии сопоставить один из другого.
/data/our-news-categories-for-list-fr/entry/title-fr/@handle
(значение узла title-fr - французский перевод заголовка категории)
/data/our-news-article-fr/entry/categories/item/@handle
Я новичок в XSLT и изо всех сил пытаюсь найти, как это сделать.
Большое спасибо.
3 ответа
Добавлять <xsl:key name="k1" match="our-news-categories-for-list-fr/entry" use="@id"/>
как дочерний элемент вашего элемента таблицы стилей XSLT. Затем используйте, например, <li><a href="{/data/params/root}/{/data/params/root-page}/our-news/categorie/{@handle}/"><xsl:value-of select="key('k1', @id)/title-fr"/></a></li>
,
В пределах xsl:for-each
инструкция повторения, контекст our-news-article-fr/entry/categories/item
, Если вы используете .
Вы выбираете текущий контекст, поэтому вы получаете английскую версию там.
Другой подход (не говоря уже о самом простом и лучшем) - просто указать выражение XPath, которое находит правильный узел. Вы можете использовать ancestor::
ось, чтобы выйти из текущего контекста data
а затем используйте свой тестовый узел. Необходимый предикат должен соответствовать текущему контексту, используя current()
функция:
<xsl:value-of select="
ancestor::data[1]/
our-news-categories-for-list-fr/
entry/
title-fr
[@handle=current()/@handle]
"/>
Если data
является корнем вашего документа, вы, очевидно, можете использовать абсолютный путь к местоположению:
/
data/
our-news-categories-for-list-fr/
entry/
title-fr
[@handle=current()/@handle]
../our-news-categories-for-list-fr/entry/title-fr/text() instead of @handle should do it
Your problem is that you are in
<our-news-article-fr>
and need to reference
<our-news-categories-for-list-fr>
так что я делаю родитель.. чтобы пройтись по дереву, а затем вниз по узлам входа