Treemonkey
Treemonkey

Reputation: 2163

xslt value-of union priority

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

Upvotes: 2

Views: 1329

Answers (3)

Marbleman
Marbleman

Reputation: 1

This post is quite old but the question is still up to date, so maybe this answer is interesting anyway:

<xsl:variable name="by" select="(Contributors/Contributor[Role='ReMixer']/Name | Attribution)[string-length(.) &gt; 0]" />

will work as well.

The union operator returns a nodelist... and a nodelist can be filtered as usual.

Upvotes: 0

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243489

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'])]

Upvotes: 4

Pavel Minaev
Pavel Minaev

Reputation: 101605

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

Upvotes: 3

Related Questions