etd_onlineguys
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?
<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?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Geert,
I thank you for this elegant and extensible solution. You make it look easy.
David
I thank you for this elegant and extensible solution. You make it look easy.
David
you are welcome David
<xsl:for-each select="//APPLICANT[
* [(name() = $filter1 and . = $filter1value) and not(string-length($filter1
|* [(name() = $filter2 and . = $filter2value) and not(string-length($filter2
]">