Link to home
Start Free TrialLog in
Avatar of etd_onlineguys
etd_onlineguysFlag for United States of America

asked on

Filtering on multiple params in XSL

Gertone helped me a lot with this and I thought I had it, but I'm still stumped.  I'm trying to use XSL to filter on multiple elements from the following XML file.  

<NODES>
  <APPLICANT>
    <NAME>Sean McGowan</NAME>
    <PREFERRED></PREFERRED>
    <FLAGGED>1</FLAGGED>
  </APPLICANT>
  <APPLICANT>
    <NAME>Carol Gillette</NAME>
    <PREFERRED>1</PREFERRED>
    <FLAGGED></FLAGGED>
</NODES>
 
I'm passing parameters to XSL with the names of the elements I want to match and the values they should match.  The hard part is that I want a rows to display whenever EITHER of the filter elements matches the desired value.   Here are the params:

  <xsl:param name="filter1" />
  <xsl:param name="filter1value" />
  <xsl:param name="filter2" />
  <xsl:param name="filter2value" />

And here is my select statement:

<xsl:for-each select="//APPLICANT[
         *      [(name() = $filter1 and . = $filter1value) or (string-length($filter1) = 0)]
                [(name() = $filter2 and . = $filter2value) or (string-length($filter2) = 0)]
]">

I pass the parameters $filter1 = "FLAGGED" &  $filter1value = "1", for example.
This works fine when either of the parameters are set, but returns no rows when both are set by passing $filter2 = "PREFERRED" &  $filter2value = "1", too .  I could use an OR statement instead, such as:

<xsl:for-each select="//APPLICANT[
         *      [(name() = $filter1 and . = $filter1value) or (string-length($filter1) = 0)]
         |*    [(name() = $filter2 and . = $filter2value) or (string-length($filter2) = 0)]
]">

But this returns true for all rows when one of the parameters isn't set.  I need to be able to filter on either or both parameters.  I think the problem with the AND method is that the name() function is looking at the XML elements one at a time.  If name() = $filter1 in the first predicate, it won't in the second.  What can I do?
Avatar of Gertone (Geert Bormans)
Gertone (Geert Bormans)
Flag of Belgium image

is this what you want

<xsl:for-each select="//APPLICANT[
         *     [(name() = $filter1 and . = $filter1value) and not(string-length($filter1) = 0)]
         |*    [(name() = $filter2 and . = $filter2value) and not(string-length($filter2) = 0)]
]">
ASKER CERTIFIED SOLUTION
Avatar of Gertone (Geert Bormans)
Gertone (Geert Bormans)
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of etd_onlineguys

ASKER

Geert,
I thank you for this elegant and extensible solution.  You make it look easy.
David
you are welcome David