2
votes

XSLT available is 1.0.

I'm working on a dual-language site in an XML-based CMS (Symphony CMS), and need to replace the English version of a category name with the French version.

This is my source 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>

This is part of the XSLT that I currently have for the French version.

<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>

The problem: the visible text of the anchor (<xsl:value-of select="."/>) gives the English version of the category title.

The handles of the following nodes match (all handles are in English), and so I'm thinking I should be able to match one from the other.

/data/our-news-categories-for-list-fr/entry/title-fr/@handle (value of title-fr node is French translation of category title)

/data/our-news-article-fr/entry/categories/item/@handle

I'm new to XSLT and am struggling to find how to do this.

Many thanks.

3
<title-fr handle="healthcare">Santé</title-en> cannot be valid tags ?MikeyKennethR
@user639175 Thanks - corrected.David Oliver
+1 for good question. See my answer to know how to do this with a simple XPath location path.Emiliano Poggi

3 Answers

1
votes

Add <xsl:key name="k1" match="our-news-categories-for-list-fr/entry" use="@id"/> as a child of your XSLT stylesheet element. Then use e.g. <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>.

1
votes
../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>

so I do a parent .. to walk up the tree and then down the entry nodes

1
votes

Within the xsl:for-each repetition instruction, the context is our-news-article-fr/entry/categories/item. If you use . you select the current context, that's why you are receiving the english version there.

Another approach (not saying the simplest and the best one) is simply specify an XPath expression which locates the correct node. You can use the ancestor:: axis to go out from the current context to data and then use your test node. The needed predicate must match against the current context using current() function:

<xsl:value-of select="
    ancestor::data[1]/
     our-news-categories-for-list-fr/
      entry/
       title-fr
       [@handle=current()/@handle]
 "/>

If data is the root of your document you can obviously use an absolute location path:

     /
     data/
      our-news-categories-for-list-fr/
       entry/
        title-fr
        [@handle=current()/@handle]