tags:

views:

162

answers:

2

I have a variable in XSLT called variable_name which I am trying to set to 1, if the Product in question has attributes with name A or B or both A & B.

<xsl:variable name="variable_name">
  <xsl:for-each select="product/attributes">
    <xsl:if test="@attributename='A' or @attributename='B'">
      <xsl:value-of select="1"/>
    </xsl:if>
  </xsl:for-each>
</xsl:variable>

Is there any way to match multiple strings using the if statement, as mine just matches if A is present or B is present. If both A & B are present, it does not set the variable to 1. Any help on this would be appreciated as I am a newbie in XSLT.

+2  A: 

You can use xsl:choose statement, it's something like switch in common programming languages:

Example:

<xsl:variable name="variable_name">
  <xsl:for-each select="product/attributes">
  <xsl:choose>
    <xsl:when test="@attributename='A'">
      1
    </xsl:when>
    <xsl:when test=" @attributename='B'">
      1
    </xsl:when>
    <!--... add other options here-->
    <xsl:otherwise>1</xsl:otherwise>
  </xsl:choose>
  </xsl:for-each>
</xsl:variable> 

This will set new variable with name variable_name with the value of attribute product/attributes.

For more info ... http://www.w3schools.comwww.w3schools.com/xsl/el_choose.asp

EDIT: And another way (a little dirty) by OP's request:

<xsl:variable name="variable_name">
  <xsl:for-each select="product/attributes">
    <xsl:if test="contains(text(), 'A') or contains(text(), 'B')">
       1
    </xsl:if>
  </xsl:for-each>
</xsl:variable> 

It will be helpful if you provide the xml you're writing your xslt against.

anthares
I tried that and it didnt seem to work
chugh97
<xsl:variable name="variable_name"> <xsl:for-each select="product/attributes"> <xsl:choose> <xsl:when test="@attributename='A'"> <xsl:value-of select="1"/> </xsl:when> <xsl:when test="@attributename='B'"> <xsl:value-of select="1"/> </xsl:when> </xsl:choose> </xsl:for-each> </xsl:variable> This did not work....
chugh97
I will fit it for you in a second. But Why you use for-each statement. What do you try to achieve ? Set multiple variables or the value of the variable to be concatenation of all attribute values ?
anthares
the foreach statement is getting the product attributes from a dynamic xml file..so can contain many attributes like a,b,c,d but I am interested in only a and b.
chugh97
So you want your variable's value to be something like '111111' as many time as attributes appear? Also, can you show a simple snippet of the xml you use?
anthares
I got it to work with two variables
chugh97
The above snipped does not work if both A and B are present in the product attributes
chugh97
You should add another when statement with 'and'
anthares
but if i add another when statement with add , it still does not work because i am looping thru the product attributes
chugh97
Is there any way to do this using contains function in xslt?
chugh97
You can get the element's attributes as a text and use the contains function but this is ugly hack IMO. It's better not to do it this way.
anthares
do you have a code snippet which does that?
chugh97
yes I updated my answer
anthares
The for-each is not necessary *at all* and should be dropped. You can do the same thing with just an XPath expression.
Tomalak
A: 

This might not help...

Is it 'legal' to have two XML element attributes with the same name?

eg. <element x="1" x="2"/>

Is this what you are trying to process?

Try parsing your XML file through xmllint or something like it to see if it is valid.

eg.

xmllint --valid the-xml-file.xml

My guess is that you will get a 'attribute redefined' error.

philcolbourn
Hint: The question does not indicate that the OP has an XML element two attributes with the same name, read again. ;)
Tomalak
Is 'OP' chugh97? If so, the code they posted 2 hours ago using anthares's suggestion suggests that they might be redefining attributes.But your suggestion to post the XML is excellent. We will then see who is the best guesser.
philcolbourn
"OP" is short for "original poster", the guy who started the thread.
Tomalak