tags:

views:

2943

answers:

5

I have XML that looks like

<answers>
   <answer>
      <question-number>1</question-number>
      <value>3</value>
      <mean xsi:nil="1" />
    </answer>
   <answer>
      <question-number>2</question-number>
      <value>2</value>
      <mean>2.3</mean>
    </answer>
   <answer>
      <question-number>3</question-number>
      <value>3</value>
      <mean xsi:nil="1" />
    </answer>
....
</answers>

I'm formatting each answer using xsl:for-each. If there is a mean present I have a graphical representation of the mean. For some potential lists of answers the mean will always be null.

At the bottom of the page I want to put a legend explaining the graphical representation of the mean. But I only want it to appear if I actually displayed a mean at all. So I want to be able to do a check, after closing the xsl:for-each, to say "do any of the answer elements have a non-null mean value?".

Really not sure how to do that.

A: 

Something like this should work. if you have any means it will return true

<xs:if test="/answers/answer/mean">You have a mean</xs:if>

I think this is what you mean.

Edit: maybe this?

<xs:if test="(count(/answers/answer/mean)==1)">You have a mean<xs:if>

Not sure if this works, but it might

<xs:if test="/answers/answer/mean != nil">You have a mean</xs:if>
Robert Gould
This appears to be checking whether there is any element called mean, whether it's null or not. In my XML example above, if all of the "mean" elements had xsi:nil="1", then I don't want to display, Thanks, though!
JacobM
Maybe I could check for the existence of an "element" one level below the mean -- like test="answers/answer/mean/*"? I'll try that.
JacobM
No, that doesn't seem to display ever.
JacobM
This test that you added -- "(count(/answers/answer/mean)==1)" -- resulted in this error: "A location path was expected, but the following token was encountered: ="
JacobM
And the next one you added -- "/answers/answer/mean != nil" -- seems to result in never displaying. Thanks, though!
JacobM
+5  A: 

do any of the answer elements have a non-null mean value? based on roberts example

<xs:if test="(count(/answers/answer/mean[not(@xsi:nil)])>0"><xs:if>

EDIT:

<xs:if test="//answer/mean[not(text())]"><xs:if>

LAST EDIT (before going home...)

<xs:if test="//answer/mean[attribute::xsi:nil]"><xs:if>
Jasper
makes sense to me -- good restatement of my question -- but in fact it's never displaying when using that test.
JacobM
The second one you posted -- not(//answer/mean/text()) -- seems to return true all the time.
JacobM
I see the second one was copy-pasted from the wrong page ;). The (now) second and third should give you the same nodeset.
Jasper
Try this http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm for testing the expressions. Also supports namespaces
Jasper
A: 

What about something like this?

  <xsl:for-each select="/answers/answer">
      <xsl:if test="mean &gt;= 0">
          ... other code ...
      </xsl:if>
  </xsl:for-each>
Dave DuPlantis
Won't this cause my legend to display once for every time there's a non-null mean? I want it to display once, only, if there are any non-null means at all, and otherwise not display.
JacobM
Yes, you'd want this outside your for-each loop, as you have in your answer below.
Dave DuPlantis
+2  A: 
<xs:if test="count(/answers/answer/mean[@xsi:nil != '1']) > 0">Mean stuff here</xs:if>

Should do what you want (count the means where the xsi:nil attribute isn't set to 1)

workmad3
Hmm. As with Jasper's, this makes sense and ought to work, but it's never displaying (i.e. never returning true, even if some of the mean elements have a numeric value). I shall keep exploring this approach.
JacobM
+1  A: 

Here's what finally worked for me:

<xsl:if test="//answers/answer/mean>0">

That is to say, "do there exist any answer elements for which the mean value is greater than zero". Fortunately I know that the mean value, if there is one, will in fact always be greater than zero -- unfortunately this isn't a generalized solution for this reason.

I still think the approach that jasper and workmad3 were taking (checking for the xsi:nil attribute) ought to work, but I couldn't get the syntax to actually... work.

Many thanks, all.

JacobM
Glad it worked out!
Robert Gould