xsl-list
[Top] [All Lists]

Re: [xsl] match by arbitrary number of criteria

2007-06-04 02:33:52
On 6/4/07, John Horner <Horner(_dot_)John(_at_)abc(_dot_)net(_dot_)au> wrote:
I've got XML roughly like this:

<items>
        <item>
                <name>foo</name>
                <subjects>
                        <subject>Science</subject>
                        <subject>Politics</subject>
                        <subject>History</subject>
                </subjects>
        </item>
        <item>
                <name>bar</name>
                <subjects>
                        <subject>Science</subject>
                        <subject>History</subject>
                        <subject>Art</subject>
                </subjects>
        </item>
</items>

Where each item, as you can see, is categorised.

I'm transforming them, using parameters for inclusion and exclusion,
roughly like this:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
        <xsl:param name="included" select="'Science'"/>
        <xsl:param name="excluded" select="'Politics'"/>
        <xsl:template match="//item">
                <xsl:if test="contains(subjects,$included) and
not(contains(subjects,$excluded))">
                        <xsl:value-of select="name"/>
                </xsl:if>
        </xsl:template>
</xsl:stylesheet>

Which selects "bar", because its subjects match the included string and
don't match the excluded string.

So, all well and good if I only ever have one of each, but now I need to
add more. What if I might have any number of inclusions and exclusions?
Say I had a config file like this:

<config>
        <included>
                <subject>Science</subject>
                <subject>History</subject>
        </included>
        <excluded>
                <subject>Politics</subject>
        </excluded>
</config>

Allowing an arbitrary number of inclusions and exclusions, how would I
efficiently test each item?

You can use the set comparison operators = and !=

If that config file you describe above is called "config.xml" then you
can compare each <item> with the values in the config:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

<xsl:variable name="config" select="document('config.xml')">

<xsl:template match="/">
        <xsl:copy-of select="//item[not($config/config/included/subject !=
current()/subjects/subject)
        ][not(subjects/subject = $config/config/excluded/subject)]"/>
</xsl:template>

</xsl:stylesheet>

Running this with your above input gives the output:

<item>
 <name>bar</name>
 <subjects>
   <subject>Science</subject>
   <subject>History</subject>
   <subject>Art</subject>
 </subjects>
</item>

cheers
andrew

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>