xsl-list
[Top] [All Lists]

RE: [xsl] Comparing attribute values with the matches() function

2008-04-07 02:30:05
Firstly, this:

@audience=.//*[(_at_)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(_at_)tonycusack(_dot_)com] 
Sent: 06 April 2008 22:28
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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::*[(_at_)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="//*[(_at_)audience=(_dot_)//*[(_at_)audience]/@audience]"><xsl:value-of
select="//*[(_at_)audience=(_dot_)//*[(_at_)audience]/@audience][1]//*[(_at_)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.


--~------------------------------------------------------------------
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>
--~--



--~------------------------------------------------------------------
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>