Re: [xsl] UNIQUE List of nodes attributes that have a particular value

Subject: Re: [xsl] UNIQUE List of nodes attributes that have a particular value
From: Andrew Watt <andrew@xxxxxxxxxxxxxx>
Date: Sun, 20 Apr 2003 10:43:29 +0100
At 14:42 19/04/2003 -0500, you wrote:
I am trying to find all the attributes in an XML document that contain a particular value.

Given the following data...

<ExampleData>
        <NodeA name="foo"/>
        <NodeA name="larry"/>
        <NodeA name="foo"/>
        <NodeB author="foo"/>
        <NodeB author="larry"/>
        <NodeC reporter="foo"/>
</ExampleData>

I would like to write an XPATH statement that returns this:

        <NodeA name="foo"/>
        <NodeB author="foo"/>
        <NodeC reporter="foo"/>

Note that I am only returning UNIQUE instances of element/attribute combinations with the attribute value.

Is this possible using XPATH?

Larry,


Perhaps you are looking for a more general solution, or perhaps you are seeking a solution which has to be accomplished inside a single XPath expression.

The following style sheet takes your data as input and produces the specified data as output (only modified to produce well-formed XML).

<?xml version='1.0'?>
<xsl:stylesheet
 version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
 >
<xsl:output method="xml" indent="yes" encoding="UTF-8" />

<xsl:template match="/">
<ExampleData>
 <xsl:apply-templates select="ExampleData/*[@*='foo']" />
</ExampleData>
</xsl:template>

<xsl:template match="*">
<xsl:if test="not( name(.)=name(preceding-sibling::*) )" >
<xsl:copy-of select="." />
</xsl:if>
</xsl:template>

</xsl:stylesheet>

The predicate in the select attribute of <xsl:apply-templates> selects only elements with an attribute containing the desired value.

The value of the test attribute on <xsl:if> tests whether or not an element with the same name (and because of the way that <xsl:apply-templates> is used, and which also has an attribute with value of "foo") is a preceding sibling. If such a preceding sibling exists, no output is produced.

Implicitly the solution assumes that there can be only one attribute on any particular element type that can have the value of "foo". It wouldn't work, as written, if for example <NodeA> could have a name attribute or a reporter attribute each of which could take a value of "foo". It would only display the first <NodeA> attribute which possesed an attribute with value of "foo".

If you want to look for uniqueness in the document, rather than uniqueness among siblings, you might use the preceding axis rather than the preceding-sibling axis.

Andrew Watt



XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list


Current Thread