[XSL-LIST Mailing List Archive Home]
[By Thread]
[By Date]
RE: [xsl] Comparing attribute values with the matches() function
Subject: RE: [xsl] Comparing attribute values with the matches() function From: "Michael Kay" <mike@xxxxxxxxxxxx> Date: Mon, 7 Apr 2008 10:29:31 +0100 |
Firstly, this: @audience=.//*[@audience]/@audience is the same as this: @audience=.//*/@audience because if an element doesn't have an @audience attribute, it will be ignored anyway. > The expression I need will be similar but require only that > the two @audience values share at least one audience identifier. I would write a function: <xsl:function name="f:overlaps" as="xs:boolean"> <xsl:param name="a1" as="attribute(audience)"/> <xsl:param name="a2" as="attribute(audience)"/> <xsl:sequence select="string-to-codepoints($a1) = string-to-codepoints($a2)"/> </xsl:function> (The "=" test, remember, tests whether any item in the first sequence is equal to any item in the second sequence). Then the condition becomes test="some $d in .//*/@audience satisfies f:overlaps(@audience, $d)" Michael Kay http://www.saxonica.com/ > -----Original Message----- > From: Tony Cusack [mailto:tony@xxxxxxxxxxxxxx] > Sent: 06 April 2008 22:28 > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > Subject: [xsl] Comparing attribute values with the matches() function > > Hello XSL list, > > I am having difficulty (with my very basic XSLT skills) > devising a test to compare attribute values. Hope you may be > able to help. > > My application filters XML content for multiple audiences > identified simply as A, B, C etc potentially up to Z. The > source is flagged with an @audience value such as 'ABC' to > indicate that it is relevant to those three audiences. As one > descends through the document the content becomes more > specific. The following snippet illustrates: > > <Publication title="Demo publication" audience="ABC"> > <Topic title="Level 1 ABC"> > <BodyText>Level 1 Content shared by all 3 audiences.</BodyText> > <Topic title="Level 2 ABC"> > <BodyText>Level 2 Content shared by all audiences.</BodyText> > <Topic title="Level 3 ABC"> > <BodyText>Level 3 Content shared by all audiences.</BodyText> > </Topic> > <Topic title="Level 3 AB" audience="AB"> > <BodyText>Level 3 Content shared by AB audiences.</BodyText> > </Topic> > <Topic title="Level 3 BC" audience="BC"> > <BodyText>Level 3 Content shared by BC audiences.</BodyText> > </Topic> > <Topic title="Level 3 AC" audience="AC"> > <BodyText>Level 3 Content shared by AC audiences.</BodyText> > </Topic> > <Topic title="Level 3 A" audience="A"> > <BodyText>Level 3 Audience A only content.</BodyText> > </Topic> > </Topic> > </Topic> > </Publication> > > Note that @audience is DTD optional everywhere except > Publication, but, as a business rule, should only ever occur > at the point where @audience narrows down. > > To filter the content I run my stylesheet once for each > audience with a global variable ($config) set to that > audience's identifier, and use the > contains() function to compare @audience values with the > global variable. > For example: > > Topic[(contains(@audience, $config)) or (not(@audience) and > ancestor::*[@audience][1][contains(@audience,$config)])]> > > For other purposes however I need to compare @audience values > with each other rather than a global variable. For example I > want to run a test at the beginning of each execution of the > stylesheet to check that the above mentioned business rule > has been observed. The contains() function won't do the trick > because, for example, ABC doesn't 'contain' AC in the relevant sense. > > I believe the XSLT 2 matches() function will achieve the > desired result but I'm afraid that when it comes to mixing > XPath expressions with Regex it all becomes too much for me. > > To give you a better idea of my approach here is an > expression which works for the = operator. > > <xsl:when > test="//*[@audience=.//*[@audience]/@audience]"><xsl:value-of > select="//*[@audience=.//*[@audience]/@audience][1]//*[@audien > ce][1]/@title" > /></xsl:when> > > In English that's "When any element has a descendant with > @audience equal to its (the ancestor's) own @audience, output > the @title of the first descendant instance of the first > ancestor instance". > > The expression I need will be similar but require only that > the two @audience values share at least one audience identifier. > > I am using Saxon b9-0-0-2j. > > Thanks very much, > Tony Cusack.
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Comparing attribute value, Florent Georges | Thread | [xsl] Suppress and test, Pankaj Chaturvedi |
RE: [xsl] How to sort a nodeset ret, Kerry, Richard | Date | RE: [xsl] Suppress and test, Pankaj Chaturvedi |
Month |