5

I think this isn't possible but would like to have a definitive answer.

XML:

  <agentlang>French</agentlang>
  ...
  <books>
    <book>
      <title>My Book</title>
      <author>Me</author>
    </book>
    <book>
      <title>XPath 101</title>
      <author>You</author>
  </book>
  ...
 </books>
 .....
 <translations>
    <translation English="title" French="titre" German="Titel" />
    <translation English="author" French="auteur" German="Autor" />
 </translations>

then in the XSL there is a simple transform of the main books info, but I want the headers to be translated according to the translation xml- something like this will work:

<xsl:value-of select="//translation[@English='title']/@French"/>
<xsl:value-of select="//translation[@English='Author']/@French"/>

But I want to replace the attribute @French with the agentlang value from the XML

I'm using MSXML / XSLT 1.0

Is there any way this can be done?

2 Answers 2

8

Yes, you can use a local-name() to find an element or attribute with a given dynamic value. I've stored the lookup value in a xsl:variable:

<xsl:variable name="lang" select="//agentlang/text()" />
<xsl:value-of select="//translation[@English='title']/@*[local-name()=$lang]" />

If namespaces are involved, it is good practice to also include a check for namespace-uri()=..., as of course there may be two elements with the same name, but in different namespaces.

Edit

In hindsight, use of a variable may make the transform easier to read / maintain, but isn't essential - this can be done directly as well:

<xsl:value-of select="//translation[@English='title']/@*[local-name()=//agentlang]" />
Sign up to request clarification or add additional context in comments.

1 Comment

thanks, this works great; I'd tried variables, it was the local-name() function that I was missing.
0

You could get the same result with a template

<xsl:template name="translate_english_to_local">
  <xsl:param name="text>

  <xsl:value-of select="//translation[@English=$text]/@*[local-name()=//agentlang]" />

</xsl:template>

Which would result into:

<xsl:call-template="translate_english_to_local">
    <xsl:with-param name="text">title</xsl:with-param>
</xsl:call-template>
  • Make the code easier to read
  • If you would change the translation library, you update the template and the rest will follow.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.