tags:

views:

53

answers:

2

Hi all

I am trying to set a variable in XSLT 1.0 as follows

 <xsl:variable name="by" select="Contributors/Contributor[Role='ReMixer']/Name | Attribution" />

The Idea is that if the Remixer Role does not exsit then the variable will take on the value of Attribution, however when testing it always takes on the value Attribution regardless.

any ideas why this happens and a solution?

update 1

This is currently what i've got working

<xsl:variable name="Remixer" select="Contributors/Contributor[Role='ReMixer']/Name" />
      <xsl:variable name="by">
            <xsl:choose>
                  <xsl:when test="$Remixer = ''">
                        <xsl:value-of select="Attribution"/>
                  </xsl:when>
                  <xsl:otherwise>
                        <xsl:value-of select="$Remixer"/>
                  </xsl:otherwise>
            </xsl:choose>
      </xsl:variable>

Would there be a shorter way of acheving the same results?

below is a copy of the xml doccument

<track>
      <attribution>Various Artists</attribution>
      <contributors>
            <contributor primary="true">
                  <role>Recording Artist</role>
                  <name country="" birth-deathyear="" part3="Cosmic Gate" part2="" part1="">Cosmic Gate</name>
            </contributor>
            <contributor primary="true">
                  <role>ReMixer</role>
                  <name country="" birth-deathyear="" part3="Gary Gee" part2="" part1="">Gary Gee</name>
            </contributor>
      </contributors>
</track>

Thanks

Sam

A: 

| in XSLT is not "or", it's an operator to make a union of two nodesets. So if both Name and Attribution exist, the value of variable by will be a nodeset consisting of those two elements. Now, when you actually try to use the variable in a context where a "value" is required - e.g. xsl:value-of, the value of the first node in the nodeset in document order is used. In your case, Attribution probably always comes first in the document, hence why it is always used.

The workaround is to use xsl:if.

Pavel Minaev
thanks for the explaination! i will post a copy of my code could you look see if theres a better way to do it please :)
Treemonkey
+2  A: 

The proper way to use this idiom is:

       $n1[$condition] | $n2[not($condition)]

selects the node $n1 iff $condition is true ()and selects $n2 iff $condition is false().

So, in your case this would be:

       Contributors/Contributor[Role='ReMixer']/Name
| 
       Attribution[not(../Contributors/Contributor[Role='ReMixer'])]
Dimitre Novatchev
Thanks for that Dimitre I wasn't thinking laterally enough for that one! works a treat. Think its opened my mind a little better into selecting preconditions :)
Treemonkey
@Dimitre: +1 Excellent answer! Also when document order is for us, and the condition is just existence, one could do `($node1|$node2)[1]`
Alejandro